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 | Date: December 3, 2009 | 2 | Date: December 3, 2009 |
| 3 | KernelVersion: 2.6.32 | 3 | KernelVersion: 2.6.32 |
| 4 | Contact: dmaengine@vger.kernel.org | 4 | Contact: dmaengine@vger.kernel.org |
| 5 | Description: Capabilities the DMA supports.Currently there are DMA_PQ, DMA_PQ_VAL, | 5 | Description: Capabilities the DMA supports.Currently there are DMA_PQ, DMA_PQ_VAL, |
| 6 | DMA_XOR,DMA_XOR_VAL,DMA_INTERRUPT. | 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 | Date: December 3, 2009 | 9 | Date: December 3, 2009 |
| 10 | KernelVersion: 2.6.32 | 10 | KernelVersion: 2.6.32 |
| 11 | Contact: dmaengine@vger.kernel.org | 11 | Contact: dmaengine@vger.kernel.org |
| 12 | Description: The number of descriptors active in the ring. | 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 | Date: December 3, 2009 | 15 | Date: December 3, 2009 |
| 16 | KernelVersion: 2.6.32 | 16 | KernelVersion: 2.6.32 |
| 17 | Contact: dmaengine@vger.kernel.org | 17 | Contact: dmaengine@vger.kernel.org |
| 18 | Description: Descriptor ring size, total number of descriptors available. | 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 | Date: December 3, 2009 | 21 | Date: December 3, 2009 |
| 22 | KernelVersion: 2.6.32 | 22 | KernelVersion: 2.6.32 |
| 23 | Contact: dmaengine@vger.kernel.org | 23 | Contact: dmaengine@vger.kernel.org |
| 24 | Description: Version of ioatdma device. | 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 | Date: August 8, 2017 | 27 | Date: August 8, 2017 |
| 28 | KernelVersion: 4.14 | 28 | KernelVersion: 4.14 |
| 29 | Contact: dmaengine@vger.kernel.org | 29 | Contact: dmaengine@vger.kernel.org |
| @@ -152,7 +152,7 @@ Description: · 151 unmodified lines | |||
| 152 | When an interface is under test, it cannot be expected | 152 | When an interface is under test, it cannot be expected |
| 153 | to pass packets as normal. | 153 | to pass packets as normal. |
| 154 | 154 | ||
| 155 | What: /sys/clas/net/<iface>/duplex | 155 | What: /sys/class/net/<iface>/duplex |
| 156 | Date: October 2009 | 156 | Date: October 2009 |
| 157 | KernelVersion: 2.6.33 | 157 | KernelVersion: 2.6.33 |
| 158 | Contact: netdev@vger.kernel.org | 158 | Contact: netdev@vger.kernel.org |
| @@ -26,6 +26,10 @@ BUILDDIR = $(obj)/output · 25 unmodified lines | |||
| 26 | PDFLATEX = xelatex | 26 | PDFLATEX = xelatex |
| 27 | LATEXOPTS = -interaction=batchmode | 27 | LATEXOPTS = -interaction=batchmode |
| 28 | 28 | ||
| 29 | ifeq ($(KBUILD_VERBOSE),0) | ||
| 30 | SPHINXOPTS += "-q" | ||
| 31 | endif | ||
| 32 | |||
| 29 | # User-friendly check for sphinx-build | 33 | # User-friendly check for sphinx-build |
| 30 | HAVE_SPHINX := $(shell if which $(SPHINXBUILD) >/dev/null 2>&1; then echo 1; else echo 0; fi) | 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 | privileges, such as allowing a user to set up user namespace UID/GID mappings. | 107 | privileges, such as allowing a user to set up user namespace UID/GID mappings. |
| 108 | 108 | ||
| 109 | Note on GID policies and setgroups() | 109 | Note on GID policies and setgroups() |
| 110 | ================== | 110 | ==================================== |
| 111 | In v5.9 we are adding support for limiting CAP_SETGID privileges as was done | 111 | In v5.9 we are adding support for limiting CAP_SETGID privileges as was done |
| 112 | previously for CAP_SETUID. However, for compatibility with common sandboxing | 112 | previously for CAP_SETUID. However, for compatibility with common sandboxing |
| 113 | related code conventions in userspace, we currently allow arbitrary | 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 | statistics of the given idle state. That information is exposed by the kernel | 478 | statistics of the given idle state. That information is exposed by the kernel |
| 479 | via ``sysfs``. | 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 | directory in ``sysfs``, where the number ``<N>`` is assigned to the given | 482 | directory in ``sysfs``, where the number ``<N>`` is assigned to the given |
| 483 | CPU at the initialization time. That directory contains a set of subdirectories | 483 | CPU at the initialization time. That directory contains a set of subdirectories |
| 484 | called :file:`state0`, :file:`state1` and so on, up to the number of idle state | 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 | residency. | 494 | residency. |
| 495 | 495 | ||
| 496 | ``below`` | 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 | a deeper idle state would have been a better match for the observed idle | 498 | a deeper idle state would have been a better match for the observed idle |
| 499 | duration. | 499 | duration. |
| 500 | 500 | ||
| @@ -300,6 +300,7 @@ Note: · 299 unmodified lines | |||
| 300 | 0: 0 1 2 3 4 5 6 7 | 300 | 0: 0 1 2 3 4 5 6 7 |
| 301 | RSS hash key: | 301 | RSS hash key: |
| 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 | 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 | netdev_tstamp_prequeue | 304 | netdev_tstamp_prequeue |
| 304 | ---------------------- | 305 | ---------------------- |
| 305 | 306 | ||
| @@ -148,3 +148,13 @@ SunXi family · 147 unmodified lines | |||
| 148 | * User Manual | 148 | * User Manual |
| 149 | 149 | ||
| 150 | http://dl.linux-sunxi.org/A64/Allwinner%20A64%20User%20Manual%20v1.0.pdf | 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 | support for Sphinx v3.0 and above is brand new. Be prepared for | 51 | support for Sphinx v3.0 and above is brand new. Be prepared for |
| 52 | possible issues in the generated output. | 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 | # Sphinx c function parser is more pedantic with regards to type | 55 | # Sphinx c function parser is more pedantic with regards to type |
| 56 | # checking. Due to that, having macros at c:function cause problems. | 56 | # checking. Due to that, having macros at c:function cause problems. |
| 57 | # Those needed to be scaped by using c_id_attributes[] array | 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 | pass:: | 295 | pass:: |
| 296 | 296 | ||
| 297 | ok 28 - kmalloc_double_kzfree | 297 | ok 28 - kmalloc_double_kzfree |
| 298 | |||
| 298 | or, if kmalloc failed:: | 299 | or, if kmalloc failed:: |
| 299 | 300 | ||
| 300 | # kmalloc_large_oob_right: ASSERTION FAILED at lib/test_kasan.c:163 | 301 | # kmalloc_large_oob_right: ASSERTION FAILED at lib/test_kasan.c:163 |
| 301 | Expected ptr is not null, but is | 302 | Expected ptr is not null, but is |
| 302 | not ok 4 - kmalloc_large_oob_right | 303 | not ok 4 - kmalloc_large_oob_right |
| 304 | |||
| 303 | or, if a KASAN report was expected, but not found:: | 305 | or, if a KASAN report was expected, but not found:: |
| 304 | 306 | ||
| 305 | # kmalloc_double_kzfree: EXPECTATION FAILED at lib/test_kasan.c:629 | 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 | config MISC_EXAMPLE_TEST | 198 | config MISC_EXAMPLE_TEST |
| 199 | bool "Test for my example" | 199 | bool "Test for my example" |
| 200 | depends on MISC_EXAMPLE && KUNIT | 200 | depends on MISC_EXAMPLE && KUNIT=y |
| 201 | 201 | ||
| 202 | and the following to ``drivers/misc/Makefile``: | 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 | ...will run the tests. | 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 | Writing new tests for other architectures | 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 | please refer the following document to know more about the binding rules | 4 | please refer the following document to know more about the binding rules |
| 5 | for these system controllers: | 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 | Required Properties: | 9 | Required Properties: |
| 10 | 10 | ||
| @@ -32,6 +32,11 @@ description: | · 31 unmodified lines | |||
| 32 | | | vint | bit | | 0 |.....|63| vintx | | 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 | Configuration of these Intmap registers that maps global events to vint is | 42 | Configuration of these Intmap registers that maps global events to vint is |
| @@ -70,6 +75,11 @@ properties: · 32 unmodified lines | |||
| 70 | - description: | | 75 | - description: | |
| 71 | "limit" specifies the limit for translation | 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 | required: | 83 | required: |
| 74 | - compatible | 84 | - compatible |
| 75 | - reg | 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 | .. kernel-doc:: fs/dax.c | 86 | .. kernel-doc:: fs/dax.c |
| 87 | :export: | 87 | :export: |
| 88 | 88 | ||
| 89 | .. kernel-doc:: fs/direct-io.c | ||
| 90 | :export: | ||
| 91 | |||
| 92 | .. kernel-doc:: fs/libfs.c | 89 | .. kernel-doc:: fs/libfs.c |
| 93 | :export: | 90 | :export: |
| 94 | 91 | ||
| @@ -83,10 +83,6 @@ AMDGPU XGMI Support · 82 unmodified lines | |||
| 83 | =================== | 83 | =================== |
| 84 | 84 | ||
| 85 | .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c | 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 | AMDGPU RAS Support | 87 | AMDGPU RAS Support |
| 92 | ================== | 88 | ================== |
| @@ -124,9 +120,6 @@ RAS VRAM Bad Pages sysfs Interface · 31 unmodified lines | |||
| 124 | .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 120 | .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c |
| 125 | :doc: AMDGPU RAS sysfs gpu_vram_bad_pages Interface | 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 | Sample Code | 123 | Sample Code |
| 131 | ----------- | 124 | ----------- |
| 132 | Sample code for testing error injection can be found here: | 125 | Sample code for testing error injection can be found here: |
| @@ -118,6 +118,12 @@ Atomic Plane Helpers · 117 unmodified lines | |||
| 118 | .. kernel-doc:: drivers/gpu/drm/i915/display/intel_atomic_plane.c | 118 | .. kernel-doc:: drivers/gpu/drm/i915/display/intel_atomic_plane.c |
| 119 | :internal: | 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 | Output Probing | 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 | integrated 12 bit SAR ADC, accessed using a PMBus interface. | 20 | integrated 12 bit SAR ADC, accessed using a PMBus interface. |
| 21 | 21 | ||
| 22 | The driver is a client driver to the core PMBus driver. Please see | 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 | Sysfs entries | 26 | Sysfs entries |
| @@ -132,6 +132,7 @@ Hardware Monitoring Kernel Drivers · 131 unmodified lines | |||
| 132 | mcp3021 | 132 | mcp3021 |
| 133 | menf21bmc | 133 | menf21bmc |
| 134 | mlxreg-fan | 134 | mlxreg-fan |
| 135 | mp2975 | ||
| 135 | nct6683 | 136 | nct6683 |
| 136 | nct6775 | 137 | nct6775 |
| 137 | nct7802 | 138 | nct7802 |
| @@ -20,6 +20,7 @@ This driver implements support for Monolithic Power Systems, Inc. (MPS) · 19 unmodified lines | |||
| 20 | vendor dual-loop, digital, multi-phase controller MP2975. | 20 | vendor dual-loop, digital, multi-phase controller MP2975. |
| 21 | 21 | ||
| 22 | This device: | 22 | This device: |
| 23 | |||
| 23 | - Supports up to two power rail. | 24 | - Supports up to two power rail. |
| 24 | - Provides 8 pulse-width modulations (PWMs), and can be configured up | 25 | - Provides 8 pulse-width modulations (PWMs), and can be configured up |
| 25 | to 8-phase operation for rail 1 and up to 4-phase operation for rail | 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 | 10-mV DAC, IMVP9 mode with 5-mV DAC. | 33 | 10-mV DAC, IMVP9 mode with 5-mV DAC. |
| 33 | 34 | ||
| 34 | Device supports: | 35 | Device supports: |
| 36 | |||
| 35 | - SVID interface. | 37 | - SVID interface. |
| 36 | - AVSBus interface. | 38 | - AVSBus interface. |
| 37 | 39 | ||
| 38 | Device complaint with: | 40 | Device complaint with: |
| 41 | |||
| 39 | - PMBus rev 1.3 interface. | 42 | - PMBus rev 1.3 interface. |
| 40 | 43 | ||
| 41 | Device supports direct format for reading output current, output voltage, | 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 | The below VID modes are supported: VR12, VR13, IMVP9. | 48 | The below VID modes are supported: VR12, VR13, IMVP9. |
| 46 | 49 | ||
| 47 | The driver provides the next attributes for the current: | 50 | The driver provides the next attributes for the current: |
| 51 | |||
| 48 | - for current in: input, maximum alarm; | 52 | - for current in: input, maximum alarm; |
| 49 | - for current out input, maximum alarm and highest values; | 53 | - for current out input, maximum alarm and highest values; |
| 50 | - for phase current: input and label. | 54 | - for phase current: input and label. |
| 51 | attributes. | 55 | attributes. |
| 56 | |||
| 52 | The driver exports the following attributes via the 'sysfs' files, where | 57 | The driver exports the following attributes via the 'sysfs' files, where |
| 58 | |||
| 53 | - 'n' is number of telemetry pages (from 1 to 2); | 59 | - 'n' is number of telemetry pages (from 1 to 2); |
| 54 | - 'k' is number of configured phases (from 1 to 8); | 60 | - 'k' is number of configured phases (from 1 to 8); |
| 55 | - indexes 1, 1*n for "iin"; | 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 | **curr[1-{2n+k}]_label** | 71 | **curr[1-{2n+k}]_label** |
| 66 | 72 | ||
| 67 | The driver provides the next attributes for the voltage: | 73 | The driver provides the next attributes for the voltage: |
| 74 | |||
| 68 | - for voltage in: input, high critical threshold, high critical alarm, all only | 75 | - for voltage in: input, high critical threshold, high critical alarm, all only |
| 69 | from page 0; | 76 | from page 0; |
| 70 | - for voltage out: input, low and high critical thresholds, low and high | 77 | - for voltage out: input, low and high critical thresholds, low and high |
| 71 | critical alarms, from pages 0 and 1; | 78 | critical alarms, from pages 0 and 1; |
| 79 | |||
| 72 | The driver exports the following attributes via the 'sysfs' files, where | 80 | The driver exports the following attributes via the 'sysfs' files, where |
| 81 | |||
| 73 | - 'n' is number of telemetry pages (from 1 to 2); | 82 | - 'n' is number of telemetry pages (from 1 to 2); |
| 74 | - indexes 1 for "iin"; | 83 | - indexes 1 for "iin"; |
| 75 | - indexes n+1, n+2 for "vout"; | 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 | **in[2-{n+1}1_lcrit_alarm** | 96 | **in[2-{n+1}1_lcrit_alarm** |
| 88 | 97 | ||
| 89 | The driver provides the next attributes for the power: | 98 | The driver provides the next attributes for the power: |
| 99 | |||
| 90 | - for power in alarm and input. | 100 | - for power in alarm and input. |
| 91 | - for power out: highest and input. | 101 | - for power out: highest and input. |
| 102 | |||
| 92 | The driver exports the following attributes via the 'sysfs' files, where | 103 | The driver exports the following attributes via the 'sysfs' files, where |
| 104 | |||
| 93 | - 'n' is number of telemetry pages (from 1 to 2); | 105 | - 'n' is number of telemetry pages (from 1 to 2); |
| 94 | - indexes 1 for "pin"; | 106 | - indexes 1 for "pin"; |
| 95 | - indexes n+1, n+2 for "pout"; | 107 | - indexes n+1, n+2 for "pout"; |
| @@ -25,3 +25,4 @@ LEDs · 24 unmodified lines | |||
| 25 | leds-lp5562 | 25 | leds-lp5562 |
| 26 | leds-lp55xx | 26 | leds-lp55xx |
| 27 | leds-mlxcpld | 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 | (4 usages * n STATEs + 1) categories: | 42 | (4 usages * n STATEs + 1) categories: |
| 43 | 43 | ||
| 44 | where the 4 usages can be: | 44 | where the 4 usages can be: |
| 45 | |||
| 45 | - 'ever held in STATE context' | 46 | - 'ever held in STATE context' |
| 46 | - 'ever held as readlock in STATE context' | 47 | - 'ever held as readlock in STATE context' |
| 47 | - 'ever held with STATE enabled' | 48 | - 'ever held with STATE enabled' |
| @@ -49,10 +50,12 @@ where the 4 usages can be: · 1 unmodified line | |||
| 49 | 50 | ||
| 50 | where the n STATEs are coded in kernel/locking/lockdep_states.h and as of | 51 | where the n STATEs are coded in kernel/locking/lockdep_states.h and as of |
| 51 | now they include: | 52 | now they include: |
| 53 | |||
| 52 | - hardirq | 54 | - hardirq |
| 53 | - softirq | 55 | - softirq |
| 54 | 56 | ||
| 55 | where the last 1 category is: | 57 | where the last 1 category is: |
| 58 | |||
| 56 | - 'ever used' [ == !unused ] | 59 | - 'ever used' [ == !unused ] |
| 57 | 60 | ||
| 58 | When locking rules are violated, these usage bits are presented in the | 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 | | | irq enabled | irq disabled | | 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 | The character '-' suggests irq is disabled because if otherwise the | 107 | The character '-' suggests irq is disabled because if otherwise the |
| @@ -216,7 +219,7 @@ looks like this:: · 111 unmodified lines | |||
| 216 | BD_MUTEX_PARTITION | 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 | In this case the locking is done on a bdev object that is known to be a | 224 | In this case the locking is done on a bdev object that is known to be a |
| 222 | partition. | 225 | partition. |
| @@ -334,7 +337,7 @@ Troubleshooting: · 111 unmodified lines | |||
| 334 | ---------------- | 337 | ---------------- |
| 335 | 338 | ||
| 336 | The validator tracks a maximum of MAX_LOCKDEP_KEYS number of lock classes. | 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 | (DEBUG_LOCKS_WARN_ON(id >= MAX_LOCKDEP_KEYS)) | 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 | The difference between recursive readers and non-recursive readers is because: | 424 | The difference between recursive readers and non-recursive readers is because: |
| 422 | recursive readers get blocked only by a write lock *holder*, while non-recursive | 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 | TASK A: TASK B: | 429 | TASK A: TASK B: |
| 426 | 430 | ||
| @@ -448,20 +452,22 @@ There are simply four block conditions: · 21 unmodified lines | |||
| 448 | 452 | ||
| 449 | Block condition matrix, Y means the row blocks the column, and N means otherwise. | 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 | (W: writers, r: non-recursive readers, R: recursive readers) | 465 | (W: writers, r: non-recursive readers, R: recursive readers) |
| 460 | 466 | ||
| 461 | 467 | ||
| 462 | acquired recursively. Unlike non-recursive read locks, recursive read locks | 468 | acquired recursively. Unlike non-recursive read locks, recursive read locks |
| 463 | only get blocked by current write lock *holders* other than write lock | 469 | only get blocked by current write lock *holders* other than write lock |
| 464 | *waiters*, for example: | 470 | *waiters*, for example:: |
| 465 | 471 | ||
| 466 | TASK A: TASK B: | 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 | even true for two non-recursive read locks). A non-recursive lock can block the | 497 | even true for two non-recursive read locks). A non-recursive lock can block the |
| 492 | corresponding recursive lock, and vice versa. | 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 | TASK A: TASK B: | 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 | dependencies, but we can show that 4 types of lock dependencies are enough for | 516 | dependencies, but we can show that 4 types of lock dependencies are enough for |
| 511 | deadlock detection. | 517 | deadlock detection. |
| 512 | 518 | ||
| 513 | For each lock dependency: | 519 | For each lock dependency:: |
| 514 | 520 | ||
| 515 | L1 -> L2 | 521 | L1 -> L2 |
| 516 | 522 | ||
| @@ -525,20 +531,25 @@ same types). · 8 unmodified lines | |||
| 525 | With the above combination for simplification, there are 4 types of dependency edges | 531 | With the above combination for simplification, there are 4 types of dependency edges |
| 526 | in the lockdep graph: | 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 | X -> Y and X is a writer and Y is a recursive reader. | 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 | X -> Y and X is a writer and Y is either a writer or non-recursive reader. | 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 | X -> Y and X is a reader (recursive or not) and Y is a recursive reader. | 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 | X -> Y and X is a reader (recursive or not) and Y is either a writer or | 548 | X -> Y and X is a reader (recursive or not) and Y is either a writer or |
| 539 | non-recursive reader. | 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 | TASK A: | 554 | TASK A: |
| 544 | 555 | ||
| @@ -592,11 +603,11 @@ circles that won't cause deadlocks. · 47 unmodified lines | |||
| 592 | 603 | ||
| 593 | Proof for sufficiency (Lemma 1): | 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 | L1 -> L2 ... -> Ln -> L1 | 608 | L1 -> L2 ... -> Ln -> L1 |
| 598 | 609 | ||
| 599 | , which means we have dependencies: | 610 | , which means we have dependencies:: |
| 600 | 611 | ||
| 601 | L1 -> L2 | 612 | L1 -> L2 |
| 602 | L2 -> L3 | 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 | for a lock held by P1. Let's name the lock Px is waiting as Lx, so since P1 is waiting | 644 | for a lock held by P1. Let's name the lock Px is waiting as Lx, so since P1 is waiting |
| 634 | for L1 and holding Ln, so we will have Ln -> L1 in the dependency graph. Similarly, | 645 | for L1 and holding Ln, so we will have Ln -> L1 in the dependency graph. Similarly, |
| 635 | we have L1 -> L2, L2 -> L3, ..., Ln-1 -> Ln in the dependency graph, which means we | 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 | Ln -> L1 -> L2 -> ... -> Ln | 649 | Ln -> L1 -> L2 -> ... -> Ln |
| 639 | 650 | ||
| @@ -24,7 +24,6 @@ fit into other categories. · 23 unmodified lines | |||
| 24 | isl29003 | 24 | isl29003 |
| 25 | lis3lv02d | 25 | lis3lv02d |
| 26 | max6875 | 26 | max6875 |
| 27 | mic/index | ||
| 28 | pci-endpoint-test | 27 | pci-endpoint-test |
| 29 | spear-pcie-gadget | 28 | spear-pcie-gadget |
| 30 | uacce | 29 | uacce |
| @@ -70,6 +70,7 @@ The ``ice`` driver reports the following versions · 69 unmodified lines | |||
| 70 | that both the name (as reported by ``fw.app.name``) and version are | 70 | that both the name (as reported by ``fw.app.name``) and version are |
| 71 | required to uniquely identify the package. | 71 | required to uniquely identify the package. |
| 72 | * - ``fw.app.bundle_id`` | 72 | * - ``fw.app.bundle_id`` |
| 73 | - running | ||
| 73 | - 0xc0000001 | 74 | - 0xc0000001 |
| 74 | - Unique identifier for the DDP package loaded in the device. Also | 75 | - Unique identifier for the DDP package loaded in the device. Also |
| 75 | referred to as the DDP Track ID. Can be used to uniquely identify | 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 | SAE J1939 defines a higher layer protocol on CAN. It implements a more | 10 | SAE J1939 defines a higher layer protocol on CAN. It implements a more |
| 11 | sophisticated addressing scheme and extends the maximum packet size above 8 | 11 | sophisticated addressing scheme and extends the maximum packet size above 8 |
| 12 | bytes. Several derived specifications exist, which differ from the original | 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 | ISO-11783 (ISOBUS). This last one specifies the so-called ETP (Extended | 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 | results in a maximum packet size of ((2 ^ 24) - 1) * 7 bytes == 111 MiB. | 16 | results in a maximum packet size of ((2 ^ 24) - 1) * 7 bytes == 111 MiB. |
| 17 | 17 | ||
| 18 | Specifications used | 18 | Specifications used |
| @@ -32,15 +32,15 @@ sockets, we found some reasons to justify a kernel implementation for the · 13 unmodified lines | |||
| 32 | addressing and transport methods used by J1939. | 32 | addressing and transport methods used by J1939. |
| 33 | 33 | ||
| 34 | * **Addressing:** when a process on an ECU communicates via J1939, it should | 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 | ECU should know the source address. Other processes should be able to reuse | 36 | ECU should know the source address. Other processes should be able to reuse |
| 37 | that address. This way, address parameters for different processes | 37 | that address. This way, address parameters for different processes |
| 38 | cooperating for the same ECU, are not duplicated. This way of working is | 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 | it well. | 40 | it well. |
| 41 | 41 | ||
| 42 | * **Dynamic addressing:** Address Claiming in J1939 is time critical. | 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 | negotiation. Putting this functionality in the kernel eliminates it as a | 44 | negotiation. Putting this functionality in the kernel eliminates it as a |
| 45 | requirement for _every_ user space process that communicates via J1939. This | 45 | requirement for _every_ user space process that communicates via J1939. This |
| 46 | results in a consistent J1939 bus with proper addressing. | 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 | The J1939 sockets operate on CAN network devices (see SocketCAN). Any J1939 | 59 | The J1939 sockets operate on CAN network devices (see SocketCAN). Any J1939 |
| 60 | user space library operating on CAN raw sockets will still operate properly. | 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 | must be taken that these two do not interfere. In practice, this means they | 62 | must be taken that these two do not interfere. In practice, this means they |
| 63 | cannot share ECU addresses. A single ECU (or virtual ECU) address is used by | 63 | cannot share ECU addresses. A single ECU (or virtual ECU) address is used by |
| 64 | the library exclusively, or by the in-kernel system exclusively. | 64 | the library exclusively, or by the in-kernel system exclusively. |
| @@ -77,13 +77,13 @@ is composed as follows: · 12 unmodified lines | |||
| 77 | 8 bits : PS (PDU Specific) | 77 | 8 bits : PS (PDU Specific) |
| 78 | 78 | ||
| 79 | In J1939-21 distinction is made between PDU1 format (where PF < 240) and PDU2 | 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 | contains a so-called Group Extension, which is part of the PGN. When using PDU2 | 81 | contains a so-called Group Extension, which is part of the PGN. When using PDU2 |
| 82 | format, the Group Extension is set in the PS-field. | 82 | format, the Group Extension is set in the PS-field. |
| 83 | 83 | ||
| 84 | On the other hand, when using PDU1 format, the PS-field contains a so-called | 84 | On the other hand, when using PDU1 format, the PS-field contains a so-called |
| 85 | Destination Address, which is _not_ part of the PGN. When communicating a PGN | 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 | of the PGN shall be set to zero. The Destination Address shall be set | 87 | of the PGN shall be set to zero. The Destination Address shall be set |
| 88 | elsewhere. | 88 | elsewhere. |
| 89 | 89 | ||
| @@ -96,15 +96,15 @@ Addressing · 6 unmodified lines | |||
| 96 | 96 | ||
| 97 | Both static and dynamic addressing methods can be used. | 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 | addresses are considered right. This responsibility is for the OEM or system | 100 | addresses are considered right. This responsibility is for the OEM or system |
| 101 | integrator. | 101 | integrator. |
| 102 | 102 | ||
| 103 | For dynamic addressing, so-called Address Claiming, extra support is foreseen | 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 | a successful address claim, the kernel keeps track of both NAME and source | 105 | a successful address claim, the kernel keeps track of both NAME and source |
| 106 | address being claimed. This serves as a base for filter schemes. By default, | 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 | Mixed mode packets (from a static to a dynamic address or vice versa) are | 109 | Mixed mode packets (from a static to a dynamic address or vice versa) are |
| 110 | allowed. The BSD sockets define separate API calls for getting/setting the | 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 | On CAN, you first need to open a socket for communicating over a CAN network. | 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 | included too. To open a socket, use: | 135 | included too. To open a socket, use: |
| 136 | 136 | ||
| 137 | .. code-block:: C | 137 | .. code-block:: C |
| 138 | 138 | ||
| 139 | s = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); | 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 | mentioned in the context of transport protocol sessions. These still deliver | 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 | supported. | 144 | supported. |
| 145 | 145 | ||
| 146 | After the successful creation of the socket, you would normally use the bind(2) | 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 | 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 | 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 | 149 | socket or use ``send(2)``, ``sendto(2)``, ``sendmsg(2)`` and the ``recv*()`` counterpart |
| 150 | operations on the socket as usual. There are also J1939 specific socket options | 150 | operations on the socket as usual. There are also J1939 specific socket options |
| 151 | described below. | 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 | local address to a socket. | 154 | local address to a socket. |
| 155 | 155 | ||
| 156 | Different from CAN is that the payload data is just the data that get send, | 156 | Different from CAN is that the payload data is just the data that get sends, |
| 157 | without it's header info. The header info is derived from the sockaddr supplied | 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 | 158 | to ``bind(2)``, ``connect(2)``, ``sendto(2)`` and ``recvfrom(2)``. A ``write(2)`` with size 4 will |
| 159 | result in a packet with 4 bytes. | 159 | result in a packet with 4 bytes. |
| 160 | 160 | ||
| 161 | The sockaddr structure has extensions for use with J1939 as specified below: | 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 | } can_addr; | 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 | specified above. | 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 | 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. | 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 | 194 | I.e. only packets with a matching PGN are received. If an ADDR or NAME is set |
| 195 | it is used as a receive filter, too. It will match the destination NAME or ADDR | 195 | it is used as a receive filter, too. It will match the destination NAME or ADDR |
| 196 | of the incoming packet. The NAME filter will work only if appropriate Address | 196 | of the incoming packet. The NAME filter will work only if appropriate Address |
| 197 | Claiming for this name was done on the CAN bus and registered/cached by the | 197 | Claiming for this name was done on the CAN bus and registered/cached by the |
| 198 | kernel. | 198 | kernel. |
| 199 | 199 | ||
| 200 | On the other hand connect(2) assigns the remote address, i.e. the destination | 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 | 201 | address. The PGN from ``connect(2)`` is used as the default PGN when sending |
| 202 | packets. If ADDR or NAME is set it will be used as the default destination ADDR | 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 | filter. It will match the source NAME or ADDR of the incoming packet. | 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 | 206 | Both ``write(2)`` and ``send(2)`` will send a packet with local address from ``bind(2)`` and the |
| 207 | the remote address from connect(2). Use sendto(2) to overwrite the destination | 207 | remote address from ``connect(2)``. Use ``sendto(2)`` to overwrite the destination |
| 208 | address. | 208 | address. |
| 209 | 209 | ||
| 210 | If can_addr.j1939.name is set (!= 0) the NAME is looked up by the kernel and | 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), | 211 | the corresponding ADDR is used. If ``can_addr.j1939.name`` is not set (== 0), |
| 212 | can_addr.j1939.addr is used. | 212 | ``can_addr.j1939.addr`` is used. |
| 213 | 213 | ||
| 214 | When creating a socket, reasonable defaults are set. Some options can be | 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 | RX path related options: | 217 | RX path related options: |
| 218 | 218 | ||
| 219 | - SO_J1939_FILTER - configure array of filters | 219 | - ``SO_J1939_FILTER`` - configure array of filters |
| 220 | - SO_J1939_PROMISC - disable filters set by bind(2) and connect(2) | 220 | - ``SO_J1939_PROMISC`` - disable filters set by ``bind(2)`` and ``connect(2)`` |
| 221 | 221 | ||
| 222 | By default no broadcast packets can be send or received. To enable sending or | 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 | .. code-block:: C | 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 | TX path related options: | 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 | Message Flags during send() and Related System Calls | 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 | supported flags are: | 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 | recvmsg(2) | 274 | recvmsg(2) |
| 275 | ^^^^^^^^^^ | 275 | ^^^^^^^^^^ |
| 276 | 276 | ||
| 277 | In most cases recvmsg(2) is needed if you want to extract more information than | 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 | 278 | ``recvfrom(2)`` can provide. For example package priority and timestamp. The |
| 279 | Destination Address, name and packet priority (if applicable) are attached to | 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, | 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, | 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 | 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. | 283 | ``priority`` and ``dst_addr``, and ``uint64_t`` for ``dst_name``. |
| 284 | 284 | ||
| 285 | .. code-block:: C | 285 | .. code-block:: C |
| 286 | 286 | ||
| @@ -305,12 +305,12 @@ Dynamic Addressing · 18 unmodified lines | |||
| 305 | 305 | ||
| 306 | Distinction has to be made between using the claimed address and doing an | 306 | Distinction has to be made between using the claimed address and doing an |
| 307 | address claim. To use an already claimed address, one has to fill in the | 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 | earlier, all further messages being sent will use that address. And the | 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 | An exception on this is PGN 0x0ee00. This is the "Address Claim/Cannot Claim | 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 | necessary. | 314 | necessary. |
| 315 | 315 | ||
| 316 | To claim an address following code example can be used: | 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 | If another ECU claims the address, the kernel will mark the NAME-SA expired. | 372 | If another ECU claims the address, the kernel will mark the NAME-SA expired. |
| 373 | No socket bound to the NAME can send packets (other than address claims). To | 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 | 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 | 375 | only ``j1939.addr`` changed to the new SA, and must then send a valid address claim |
| 376 | packet. This restarts the state machine in the kernel (and any other | 376 | packet. This restarts the state machine in the kernel (and any other |
| 377 | participant on the bus) for this NAME. | 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 | default Address Claiming daemon. | 380 | default Address Claiming daemon. |
| 381 | 381 | ||
| 382 | Send Examples | 382 | Send Examples |
| @@ -403,8 +403,8 @@ Bind: · 20 unmodified lines | |||
| 403 | 403 | ||
| 404 | bind(sock, (struct sockaddr *)&baddr, sizeof(baddr)); | 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, | 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). | 407 | at this point we can use only ``sendto(2)`` or ``sendmsg(2)``. |
| 408 | 408 | ||
| 409 | Send: | 409 | Send: |
| 410 | 410 | ||
| @@ -414,8 +414,8 @@ Send: · 3 unmodified lines | |||
| 414 | .can_family = AF_CAN, | 414 | .can_family = AF_CAN, |
| 415 | .can_addr.j1939 = { | 415 | .can_addr.j1939 = { |
| 416 | .name = J1939_NO_NAME; | 416 | .name = J1939_NO_NAME; |
| 417 | .pgn = 0x30, | 417 | .addr = 0x30, |
| 418 | .addr = 0x12300, | 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 | translated to netlink attributes when dumped. Drivers must not overwrite | 175 | translated to netlink attributes when dumped. Drivers must not overwrite |
| 176 | the statistics they don't report with 0. | 176 | the statistics they don't report with 0. |
| 177 | 177 | ||
| 178 | .. kernel-doc:: include/linux/ethtool.h | 178 | - ethtool_pause_stats() |
| 179 | :identifiers: ethtool_pause_stats | ||
| @@ -15,6 +15,14 @@ else: · 14 unmodified lines | |||
| 15 | import re | 15 | import re |
| 16 | from itertools import chain | 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 | # Regex nastiness. Of course. | 27 | # Regex nastiness. Of course. |
| 20 | # Try to identify "function()" that's not already marked up some | 28 | # Try to identify "function()" that's not already marked up some |
| @@ -22,22 +30,22 @@ from itertools import chain · 1 unmodified line | |||
| 22 | # :c:func: block (i.e. ":c:func:`mmap()`s" flakes out), so the last | 30 | # :c:func: block (i.e. ":c:func:`mmap()`s" flakes out), so the last |
| 23 | # bit tries to restrict matches to things that won't create trouble. | 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 | # Sphinx 2 uses the same :c:type role for struct, union, enum and typedef | 36 | # Sphinx 2 uses the same :c:type role for struct, union, enum and typedef |
| 29 | # | 37 | # |
| 30 | RE_generic_type = re.compile(r'\b(struct|union|enum|typedef)\s+([a-zA-Z_]\w+)', | 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 | # Sphinx 3 uses a different C role for each one of struct, union, enum and | 42 | # Sphinx 3 uses a different C role for each one of struct, union, enum and |
| 35 | # typedef | 43 | # typedef |
| 36 | # | 44 | # |
| 37 | RE_struct = re.compile(r'\b(struct)\s+([a-zA-Z_]\w+)', flags=re.ASCII) | 45 | RE_struct = re.compile(r'\b(struct)\s+([a-zA-Z_]\w+)', flags=ascii_p3) |
| 38 | RE_union = re.compile(r'\b(union)\s+([a-zA-Z_]\w+)', flags=re.ASCII) | 46 | RE_union = re.compile(r'\b(union)\s+([a-zA-Z_]\w+)', flags=ascii_p3) |
| 39 | RE_enum = re.compile(r'\b(enum)\s+([a-zA-Z_]\w+)', flags=re.ASCII) | 47 | RE_enum = re.compile(r'\b(enum)\s+([a-zA-Z_]\w+)', flags=ascii_p3) |
| 40 | RE_typedef = re.compile(r'\b(typedef)\s+([a-zA-Z_]\w+)', flags=re.ASCII) | 48 | RE_typedef = re.compile(r'\b(typedef)\s+([a-zA-Z_]\w+)', flags=ascii_p3) |
| 41 | 49 | ||
| 42 | # | 50 | # |
| 43 | # Detects a reference to a documentation page of the form Documentation/... with | 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 | spec_ctrl | 22 | spec_ctrl |
| 23 | accelerators/ocxl | 23 | accelerators/ocxl |
| 24 | ioctl/index | 24 | ioctl/index |
| 25 | iommu | ||
| 25 | media/index | 26 | media/index |
| 26 | 27 | ||
| 27 | .. only:: subproject and html | 28 | .. only:: subproject and html |
| @@ -934,7 +934,7 @@ M: Evan Quan <evan.quan@amd.com> · 933 unmodified lines | |||
| 934 | L: amd-gfx@lists.freedesktop.org | 934 | L: amd-gfx@lists.freedesktop.org |
| 935 | S: Supported | 935 | S: Supported |
| 936 | T: git git://people.freedesktop.org/~agd5f/linux | 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 | AMD SEATTLE DEVICE TREE SUPPORT | 939 | AMD SEATTLE DEVICE TREE SUPPORT |
| 940 | M: Brijesh Singh <brijeshkumar.singh@amd.com> | 940 | M: Brijesh Singh <brijeshkumar.singh@amd.com> |
| @@ -978,7 +978,7 @@ M: Michael Hennerich <Michael.Hennerich@analog.com> · 37 unmodified lines | |||
| 978 | L: linux-iio@vger.kernel.org | 978 | L: linux-iio@vger.kernel.org |
| 979 | S: Supported | 979 | S: Supported |
| 980 | W: http://ez.analog.com/community/linux-device-drivers | 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 | F: drivers/iio/adc/ad7768-1.c | 982 | F: drivers/iio/adc/ad7768-1.c |
| 983 | 983 | ||
| 984 | ANALOG DEVICES INC AD7780 DRIVER | 984 | ANALOG DEVICES INC AD7780 DRIVER |
| @@ -3857,7 +3857,7 @@ M: Roger Quadros <rogerq@ti.com> · 2872 unmodified lines | |||
| 3857 | L: linux-usb@vger.kernel.org | 3857 | L: linux-usb@vger.kernel.org |
| 3858 | S: Maintained | 3858 | S: Maintained |
| 3859 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git | 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 | F: drivers/usb/cdns3/ | 3861 | F: drivers/usb/cdns3/ |
| 3862 | 3862 | ||
| 3863 | CADET FM/AM RADIO RECEIVER DRIVER | 3863 | CADET FM/AM RADIO RECEIVER DRIVER |
| @@ -7923,7 +7923,7 @@ HISILICON LPC BUS DRIVER · 4059 unmodified lines | |||
| 7923 | M: john.garry@huawei.com | 7923 | M: john.garry@huawei.com |
| 7924 | S: Maintained | 7924 | S: Maintained |
| 7925 | W: http://www.hisilicon.com | 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 | F: drivers/bus/hisi_lpc.c | 7927 | F: drivers/bus/hisi_lpc.c |
| 7928 | 7928 | ||
| 7929 | HISILICON NETWORK SUBSYSTEM 3 DRIVER (HNS3) | 7929 | HISILICON NETWORK SUBSYSTEM 3 DRIVER (HNS3) |
| @@ -11177,7 +11177,7 @@ F: Documentation/devicetree/bindings/input/touchscreen/melfas_mip4.txt · 3247 unmodified lines | |||
| 11177 | F: drivers/input/touchscreen/melfas_mip4.c | 11177 | F: drivers/input/touchscreen/melfas_mip4.c |
| 11178 | 11178 | ||
| 11179 | MELLANOX BLUEFIELD I2C DRIVER | 11179 | MELLANOX BLUEFIELD I2C DRIVER |
| 11180 | M: Khalil Blaiech <kblaiech@mellanox.com> | 11180 | M: Khalil Blaiech <kblaiech@nvidia.com> |
| 11181 | L: linux-i2c@vger.kernel.org | 11181 | L: linux-i2c@vger.kernel.org |
| 11182 | S: Supported | 11182 | S: Supported |
| 11183 | F: drivers/i2c/busses/i2c-mlxbf.c | 11183 | F: drivers/i2c/busses/i2c-mlxbf.c |
| @@ -14541,6 +14541,14 @@ F: Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml · 3357 unmodified lines | |||
| 14541 | F: drivers/mailbox/qcom-ipcc.c | 14541 | F: drivers/mailbox/qcom-ipcc.c |
| 14542 | F: include/dt-bindings/mailbox/qcom-ipcc.h | 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 | QUALCOMM RMNET DRIVER | 14552 | QUALCOMM RMNET DRIVER |
| 14545 | M: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org> | 14553 | M: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org> |
| 14546 | M: Sean Tranchetti <stranche@codeaurora.org> | 14554 | M: Sean Tranchetti <stranche@codeaurora.org> |
| @@ -14896,7 +14904,6 @@ RENESAS ETHERNET DRIVERS · 349 unmodified lines | |||
| 14896 | R: Sergei Shtylyov <sergei.shtylyov@gmail.com> | 14904 | R: Sergei Shtylyov <sergei.shtylyov@gmail.com> |
| 14897 | L: netdev@vger.kernel.org | 14905 | L: netdev@vger.kernel.org |
| 14898 | L: linux-renesas-soc@vger.kernel.org | 14906 | L: linux-renesas-soc@vger.kernel.org |
| 14899 | F: Documentation/devicetree/bindings/net/renesas,*.txt | ||
| 14900 | F: Documentation/devicetree/bindings/net/renesas,*.yaml | 14907 | F: Documentation/devicetree/bindings/net/renesas,*.yaml |
| 14901 | F: drivers/net/ethernet/renesas/ | 14908 | F: drivers/net/ethernet/renesas/ |
| 14902 | F: include/linux/sh_eth.h | 14909 | F: include/linux/sh_eth.h |
| @@ -18097,7 +18104,7 @@ M: Yu Chen <chenyu56@huawei.com> · 3194 unmodified lines | |||
| 18097 | M: Binghui Wang <wangbinghui@hisilicon.com> | 18104 | M: Binghui Wang <wangbinghui@hisilicon.com> |
| 18098 | L: linux-usb@vger.kernel.org | 18105 | L: linux-usb@vger.kernel.org |
| 18099 | S: Maintained | 18106 | S: Maintained |
| 18100 | F: Documentation/devicetree/bindings/phy/phy-hi3660-usb3.txt | 18107 | F: Documentation/devicetree/bindings/phy/hisilicon,hi3660-usb3.yaml |
| 18101 | F: drivers/phy/hisilicon/phy-hi3660-usb3.c | 18108 | F: drivers/phy/hisilicon/phy-hi3660-usb3.c |
| 18102 | 18109 | ||
| 18103 | USB ISP116X DRIVER | 18110 | USB ISP116X DRIVER |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 5 | 2 | VERSION = 5 |
| 3 | PATCHLEVEL = 10 | 3 | PATCHLEVEL = 10 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc2 | 5 | EXTRAVERSION = -rc3 |
| 6 | NAME = Kleptomaniac Octopus | 6 | NAME = Kleptomaniac Octopus |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -67,7 +67,22 @@ · 66 unmodified lines | |||
| 67 | sr r5, [ARC_REG_LPB_CTRL] | 67 | sr r5, [ARC_REG_LPB_CTRL] |
| 68 | 1: | 68 | 1: |
| 69 | #endif /* CONFIG_ARC_LPB_DISABLE */ | 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 | ; Config DSP_CTRL properly, so kernel may use integer multiply, | 86 | ; Config DSP_CTRL properly, so kernel may use integer multiply, |
| 72 | ; multiply-accumulate, and divide operations | 87 | ; multiply-accumulate, and divide operations |
| 73 | DSP_EARLY_INIT | 88 | DSP_EARLY_INIT |
| @@ -112,7 +112,7 @@ arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs, · 111 unmodified lines | |||
| 112 | int (*consumer_fn) (unsigned int, void *), void *arg) | 112 | int (*consumer_fn) (unsigned int, void *), void *arg) |
| 113 | { | 113 | { |
| 114 | #ifdef CONFIG_ARC_DW2_UNWIND | 114 | #ifdef CONFIG_ARC_DW2_UNWIND |
| 115 | int ret = 0; | 115 | int ret = 0, cnt = 0; |
| 116 | unsigned int address; | 116 | unsigned int address; |
| 117 | struct unwind_frame_info frame_info; | 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 | break; | 132 | break; |
| 133 | 133 | ||
| 134 | frame_info.regs.r63 = frame_info.regs.r31; | 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 | return address; /* return the last address it saw */ | 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 | #define ARC_CCM_UNUSED_ADDR 0x60000000 | 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 | #define ARC_PERIPHERAL_BASE 0xf0000000 | 21 | #define ARC_PERIPHERAL_BASE 0xf0000000 |
| 38 | #define CREG_BASE (ARC_PERIPHERAL_BASE + 0x1000) | 22 | #define CREG_BASE (ARC_PERIPHERAL_BASE + 0x1000) |
| @@ -339,5 +323,4 @@ static const char *hsdk_compat[] __initconst = { · 300 unmodified lines | |||
| 339 | MACHINE_START(SIMULATION, "hsdk") | 323 | MACHINE_START(SIMULATION, "hsdk") |
| 340 | .dt_compat = hsdk_compat, | 324 | .dt_compat = hsdk_compat, |
| 341 | .init_early = hsdk_init_early, | 325 | .init_early = hsdk_init_early, |
| 342 | .init_per_cpu = hsdk_init_per_cpu, | ||
| 343 | MACHINE_END | 326 | MACHINE_END |
| @@ -354,8 +354,8 @@ static void __init free_highpages(void) · 353 unmodified lines | |||
| 354 | /* set highmem page free */ | 354 | /* set highmem page free */ |
| 355 | for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, | 355 | for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, |
| 356 | &range_start, &range_end, NULL) { | 356 | &range_start, &range_end, NULL) { |
| 357 | unsigned long start = PHYS_PFN(range_start); | 357 | unsigned long start = PFN_UP(range_start); |
| 358 | unsigned long end = PHYS_PFN(range_end); | 358 | unsigned long end = PFN_DOWN(range_end); |
| 359 | 359 | ||
| 360 | /* Ignore complete lowmem entries */ | 360 | /* Ignore complete lowmem entries */ |
| 361 | if (end <= max_low) | 361 | if (end <= max_low) |
| @@ -1002,7 +1002,7 @@ config NUMA · 1001 unmodified lines | |||
| 1002 | config NODES_SHIFT | 1002 | config NODES_SHIFT |
| 1003 | int "Maximum NUMA Nodes (as a power of 2)" | 1003 | int "Maximum NUMA Nodes (as a power of 2)" |
| 1004 | range 1 10 | 1004 | range 1 10 |
| 1005 | default "2" | 1005 | default "4" |
| 1006 | depends on NEED_MULTIPLE_NODES | 1006 | depends on NEED_MULTIPLE_NODES |
| 1007 | help | 1007 | help |
| 1008 | Specify the maximum number of NUMA Nodes available on the target | 1008 | Specify the maximum number of NUMA Nodes available on the target |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | |||
| 10 | * #imm16 values used for BRK instruction generation | 10 | * #imm16 values used for BRK instruction generation |
| 11 | * 0x004: for installing kprobes | 11 | * 0x004: for installing kprobes |
| 12 | * 0x005: for installing uprobes | 12 | * 0x005: for installing uprobes |
| 13 | * 0x006: for kprobe software single-step | ||
| 13 | * Allowed values for kgdb are 0x400 - 0x7ff | 14 | * Allowed values for kgdb are 0x400 - 0x7ff |
| 14 | * 0x100: for triggering a fault on purpose (reserved) | 15 | * 0x100: for triggering a fault on purpose (reserved) |
| 15 | * 0x400: for dynamic BRK instruction | 16 | * 0x400: for dynamic BRK instruction |
| @@ -19,6 +20,7 @@ · 3 unmodified lines | |||
| 19 | */ | 20 | */ |
| 20 | #define KPROBES_BRK_IMM 0x004 | 21 | #define KPROBES_BRK_IMM 0x004 |
| 21 | #define UPROBES_BRK_IMM 0x005 | 22 | #define UPROBES_BRK_IMM 0x005 |
| 23 | #define KPROBES_BRK_SS_IMM 0x006 | ||
| 22 | #define FAULT_BRK_IMM 0x100 | 24 | #define FAULT_BRK_IMM 0x100 |
| 23 | #define KGDB_DYN_DBG_BRK_IMM 0x400 | 25 | #define KGDB_DYN_DBG_BRK_IMM 0x400 |
| 24 | #define KGDB_COMPILED_DBG_BRK_IMM 0x401 | 26 | #define KGDB_COMPILED_DBG_BRK_IMM 0x401 |
| @@ -53,6 +53,7 @@ · 52 unmodified lines | |||
| 53 | 53 | ||
| 54 | /* kprobes BRK opcodes with ESR encoding */ | 54 | /* kprobes BRK opcodes with ESR encoding */ |
| 55 | #define BRK64_OPCODE_KPROBES (AARCH64_BREAK_MON | (KPROBES_BRK_IMM << 5)) | 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 | /* uprobes BRK opcodes with ESR encoding */ | 57 | /* uprobes BRK opcodes with ESR encoding */ |
| 57 | #define BRK64_OPCODE_UPROBES (AARCH64_BREAK_MON | (UPROBES_BRK_IMM << 5)) | 58 | #define BRK64_OPCODE_UPROBES (AARCH64_BREAK_MON | (UPROBES_BRK_IMM << 5)) |
| 58 | 59 | ||
| @@ -16,7 +16,7 @@ · 15 unmodified lines | |||
| 16 | #include <linux/percpu.h> | 16 | #include <linux/percpu.h> |
| 17 | 17 | ||
| 18 | #define __ARCH_WANT_KPROBES_INSN_SLOT | 18 | #define __ARCH_WANT_KPROBES_INSN_SLOT |
| 19 | #define MAX_INSN_SIZE 1 | 19 | #define MAX_INSN_SIZE 2 |
| 20 | 20 | ||
| 21 | #define flush_insn_slot(p) do { } while (0) | 21 | #define flush_insn_slot(p) do { } while (0) |
| 22 | #define kretprobe_blacklist_size 0 | 22 | #define kretprobe_blacklist_size 0 |
| @@ -43,7 +43,7 @@ static void *image_load(struct kimage *image, · 42 unmodified lines | |||
| 43 | u64 flags, value; | 43 | u64 flags, value; |
| 44 | bool be_image, be_kernel; | 44 | bool be_image, be_kernel; |
| 45 | struct kexec_buf kbuf; | 45 | struct kexec_buf kbuf; |
| 46 | unsigned long text_offset; | 46 | unsigned long text_offset, kernel_segment_number; |
| 47 | struct kexec_segment *kernel_segment; | 47 | struct kexec_segment *kernel_segment; |
| 48 | int ret; | 48 | int ret; |
| 49 | 49 | ||
| @@ -88,11 +88,37 @@ static void *image_load(struct kimage *image, · 38 unmodified lines | |||
| 88 | /* Adjust kernel segment with TEXT_OFFSET */ | 88 | /* Adjust kernel segment with TEXT_OFFSET */ |
| 89 | kbuf.memsz += text_offset; | 89 | kbuf.memsz += text_offset; |
| 90 | 90 | ||
| 91 | ret = kexec_add_buffer(&kbuf); | 91 | kernel_segment_number = image->nr_segments; |
| 92 | if (ret) | 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 | return ERR_PTR(ret); | 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 | kernel_segment->mem += text_offset; | 122 | kernel_segment->mem += text_offset; |
| 97 | kernel_segment->memsz -= text_offset; | 123 | kernel_segment->memsz -= text_offset; |
| 98 | image->start = kernel_segment->mem; | 124 | image->start = kernel_segment->mem; |
| @@ -101,12 +127,7 @@ static void *image_load(struct kimage *image, · 2 unmodified lines | |||
| 101 | kernel_segment->mem, kbuf.bufsz, | 127 | kernel_segment->mem, kbuf.bufsz, |
| 102 | kernel_segment->memsz); | 128 | kernel_segment->memsz); |
| 103 | 129 | ||
| 104 | /* Load additional data */ | 130 | return 0; |
| 105 | ret = load_other_segments(image, | ||
| 106 | kernel_segment->mem, kernel_segment->memsz, | ||
| 107 | initrd, initrd_len, cmdline); | ||
| 108 | |||
| 109 | return ERR_PTR(ret); | ||
| 110 | } | 131 | } |
| 111 | 132 | ||
| 112 | #ifdef CONFIG_KEXEC_IMAGE_VERIFY_SIG | 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 | return ret; | 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 | int load_other_segments(struct kimage *image, | 248 | int load_other_segments(struct kimage *image, |
| 244 | unsigned long kernel_load_addr, | 249 | unsigned long kernel_load_addr, |
| 245 | unsigned long kernel_size, | 250 | unsigned long kernel_size, |
| @@ -248,7 +253,8 @@ int load_other_segments(struct kimage *image, · 2 unmodified lines | |||
| 248 | { | 253 | { |
| 249 | struct kexec_buf kbuf; | 254 | struct kexec_buf kbuf; |
| 250 | void *headers, *dtb = NULL; | 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 | int ret = 0; | 258 | int ret = 0; |
| 253 | 259 | ||
| 254 | kbuf.image = image; | 260 | kbuf.image = image; |
| @@ -334,6 +340,7 @@ int load_other_segments(struct kimage *image, · 79 unmodified lines | |||
| 334 | return 0; | 340 | return 0; |
| 335 | 341 | ||
| 336 | out_err: | 342 | out_err: |
| 343 | image->nr_segments = orig_segments; | ||
| 337 | vfree(dtb); | 344 | vfree(dtb); |
| 338 | return ret; | 345 | return ret; |
| 339 | } | 346 | } |
| @@ -36,25 +36,16 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); · 35 unmodified lines | |||
| 36 | static void __kprobes | 36 | static void __kprobes |
| 37 | post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *); | 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 | static void __kprobes arch_prepare_ss_slot(struct kprobe *p) | 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 | /* prepare insn slot */ | 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), | 48 | flush_icache_range((uintptr_t)addr, (uintptr_t)(addr + MAX_INSN_SIZE)); |
| 56 | (uintptr_t) (p->ainsn.api.insn) + | ||
| 57 | MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); | ||
| 58 | 49 | ||
| 59 | /* | 50 | /* |
| 60 | * Needs restoring of return address after stepping xol. | 51 | * Needs restoring of return address after stepping xol. |
| @@ -128,13 +119,18 @@ void *alloc_insn_page(void) · 67 unmodified lines | |||
| 128 | /* arm kprobe: install breakpoint in text */ | 119 | /* arm kprobe: install breakpoint in text */ |
| 129 | void __kprobes arch_arm_kprobe(struct kprobe *p) | 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 | /* disarm kprobe: remove breakpoint from text */ | 128 | /* disarm kprobe: remove breakpoint from text */ |
| 135 | void __kprobes arch_disarm_kprobe(struct kprobe *p) | 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 | void __kprobes arch_remove_kprobe(struct kprobe *p) | 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 | 162 | * Mask all of DAIF while executing the instruction out-of-line, to keep things |
| 167 | * reenabled until after single-step mode ends. | 163 | * simple and avoid nesting exceptions. Interrupts do have to be disabled since |
| 168 | * Without disabling interrupt on local CPU, there is a chance of | 164 | * the kprobe state is per-CPU and doesn't get migrated. |
| 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. | ||
| 172 | */ | 165 | */ |
| 173 | static void __kprobes kprobes_save_local_irqflag(struct kprobe_ctlblk *kcb, | 166 | static void __kprobes kprobes_save_local_irqflag(struct kprobe_ctlblk *kcb, |
| 174 | struct pt_regs *regs) | 167 | struct pt_regs *regs) |
| 175 | { | 168 | { |
| 176 | kcb->saved_irqflag = regs->pstate & DAIF_MASK; | 169 | kcb->saved_irqflag = regs->pstate & DAIF_MASK; |
| 177 | regs->pstate |= PSR_I_BIT; | 170 | regs->pstate |= DAIF_MASK; |
| 178 | /* Unmask PSTATE.D for enabling software step exceptions. */ | ||
| 179 | regs->pstate &= ~PSR_D_BIT; | ||
| 180 | } | 171 | } |
| 181 | 172 | ||
| 182 | static void __kprobes kprobes_restore_local_irqflag(struct kprobe_ctlblk *kcb, | 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 | slot = (unsigned long)p->ainsn.api.insn; | 210 | slot = (unsigned long)p->ainsn.api.insn; |
| 220 | 211 | ||
| 221 | set_ss_context(kcb, slot); /* mark pending ss */ | 212 | set_ss_context(kcb, slot); /* mark pending ss */ |
| 222 | |||
| 223 | /* IRQs and single stepping do not mix well. */ | ||
| 224 | kprobes_save_local_irqflag(kcb, regs); | 213 | kprobes_save_local_irqflag(kcb, regs); |
| 225 | kernel_enable_single_step(regs); | ||
| 226 | instruction_pointer_set(regs, slot); | 214 | instruction_pointer_set(regs, slot); |
| 227 | } else { | 215 | } else { |
| 228 | /* insn simulation */ | 216 | /* insn simulation */ |
| @@ -273,12 +261,8 @@ post_kprobe_handler(struct kprobe_ctlblk *kcb, struct pt_regs *regs) · 44 unmodified lines | |||
| 273 | } | 261 | } |
| 274 | /* call post handler */ | 262 | /* call post handler */ |
| 275 | kcb->kprobe_status = KPROBE_HIT_SSDONE; | 263 | kcb->kprobe_status = KPROBE_HIT_SSDONE; |
| 276 | if (cur->post_handler) { | 264 | if (cur->post_handler) |
| 277 | /* post_handler can hit breakpoint and single step | ||
| 278 | * again, so we enable D-flag for recursive exception. | ||
| 279 | */ | ||
| 280 | cur->post_handler(cur, regs, 0); | 265 | cur->post_handler(cur, regs, 0); |
| 281 | } | ||
| 282 | 266 | ||
| 283 | reset_current_kprobe(); | 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 | if (!instruction_pointer(regs)) | 286 | if (!instruction_pointer(regs)) |
| 303 | BUG(); | 287 | BUG(); |
| 304 | 288 | ||
| 305 | kernel_disable_single_step(); | ||
| 306 | |||
| 307 | if (kcb->kprobe_status == KPROBE_REENTER) | 289 | if (kcb->kprobe_status == KPROBE_REENTER) |
| 308 | restore_previous_kprobe(kcb); | 290 | restore_previous_kprobe(kcb); |
| 309 | else | 291 | else |
| @@ -365,10 +347,6 @@ static void __kprobes kprobe_handler(struct pt_regs *regs) · 55 unmodified lines | |||
| 365 | * pre-handler and it returned non-zero, it will | 347 | * pre-handler and it returned non-zero, it will |
| 366 | * modify the execution path and no need to single | 348 | * modify the execution path and no need to single |
| 367 | * stepping. Let's just reset current kprobe and exit. | 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 | if (!p->pre_handler || !p->pre_handler(p, regs)) { | 351 | if (!p->pre_handler || !p->pre_handler(p, regs)) { |
| 374 | setup_singlestep(p, regs, kcb, 0); | 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 | static int __kprobes | 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 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 382 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
| 405 | int retval; | 383 | int retval; |
| @@ -409,16 +387,15 @@ kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr) · 3 unmodified lines | |||
| 409 | 387 | ||
| 410 | if (retval == DBG_HOOK_HANDLED) { | 388 | if (retval == DBG_HOOK_HANDLED) { |
| 411 | kprobes_restore_local_irqflag(kcb, regs); | 389 | kprobes_restore_local_irqflag(kcb, regs); |
| 412 | kernel_disable_single_step(); | ||
| 413 | |||
| 414 | post_kprobe_handler(kcb, regs); | 390 | post_kprobe_handler(kcb, regs); |
| 415 | } | 391 | } |
| 416 | 392 | ||
| 417 | return retval; | 393 | return retval; |
| 418 | } | 394 | } |
| 419 | 395 | ||
| 420 | static struct step_hook kprobes_step_hook = { | 396 | static struct break_hook kprobes_break_ss_hook = { |
| 421 | .fn = kprobe_single_step_handler, | 397 | .imm = KPROBES_BRK_SS_IMM, |
| 398 | .fn = kprobe_breakpoint_ss_handler, | ||
| 422 | }; | 399 | }; |
| 423 | 400 | ||
| 424 | static int __kprobes | 401 | static int __kprobes |
| @@ -486,7 +463,7 @@ int __kprobes arch_trampoline_kprobe(struct kprobe *p) · 61 unmodified lines | |||
| 486 | int __init arch_init_kprobes(void) | 463 | int __init arch_init_kprobes(void) |
| 487 | { | 464 | { |
| 488 | register_kernel_break_hook(&kprobes_break_hook); | 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 | return 0; | 468 | return 0; |
| 492 | } | 469 | } |
| @@ -63,7 +63,7 @@ static inline void restore_user_access(unsigned long flags) · 62 unmodified lines | |||
| 63 | static inline bool | 63 | static inline bool |
| 64 | bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) | 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 | "Bug: fault blocked by AP register !"); | 67 | "Bug: fault blocked by AP register !"); |
| 68 | } | 68 | } |
| 69 | 69 | ||
| @@ -33,19 +33,18 @@ · 32 unmodified lines | |||
| 33 | * respectively NA for All or X for Supervisor and no access for User. | 33 | * respectively NA for All or X for Supervisor and no access for User. |
| 34 | * Then we use the APG to say whether accesses are according to Page rules or | 34 | * Then we use the APG to say whether accesses are according to Page rules or |
| 35 | * "all Supervisor" rules (Access to all) | 35 | * "all Supervisor" rules (Access to all) |
| 36 | * Therefore, we define 2 APG groups. lsb is _PMD_USER | 36 | * _PAGE_ACCESSED is also managed via APG. When _PAGE_ACCESSED is not set, say |
| 37 | * 0 => Kernel => 01 (all accesses performed according to page definition) | 37 | * "all User" rules, that will lead to NA for all. |
| 38 | * 1 => User => 00 (all accesses performed as supervisor iaw page definition) | 38 | * Therefore, we define 4 APG groups. lsb is _PAGE_ACCESSED |
| 39 | * 2-15 => Not Used | 39 | * 0 => Kernel => 11 (all accesses performed according as user iaw page definition) |
| 40 | */ | 40 | * 1 => Kernel+Accessed => 01 (all accesses performed according to page definition) |
| 41 | #define MI_APG_INIT 0x40000000 | 41 | * 2 => User => 11 (all accesses performed according as user iaw page definition) |
| 42 | 42 | * 3 => User+Accessed => 00 (all accesses performed as supervisor iaw page definition) for INIT | |
| 43 | /* | 43 | * => 10 (all accesses performed according to swaped page definition) for KUEP |
| 44 | * 0 => Kernel => 01 (all accesses performed according to page definition) | 44 | * 4-15 => Not Used |
| 45 | * 1 => User => 10 (all accesses performed according to swaped page definition) | 45 | */ |
| 46 | * 2-15 => Not Used | 46 | #define MI_APG_INIT 0xdc000000 |
| 47 | */ | 47 | #define MI_APG_KUEP 0xde000000 |
| 48 | #define MI_APG_KUEP 0x60000000 | ||
| 49 | 48 | ||
| 50 | /* The effective page number register. When read, contains the information | 49 | /* The effective page number register. When read, contains the information |
| 51 | * about the last instruction TLB miss. When MI_RPN is written, bits in | 50 | * about the last instruction TLB miss. When MI_RPN is written, bits in |
| @@ -106,25 +105,9 @@ · 54 unmodified lines | |||
| 106 | #define MD_Ks 0x80000000 /* Should not be set */ | 105 | #define MD_Ks 0x80000000 /* Should not be set */ |
| 107 | #define MD_Kp 0x40000000 /* Should always be set */ | 106 | #define MD_Kp 0x40000000 /* Should always be set */ |
| 108 | 107 | ||
| 109 | /* | 108 | /* See explanation above at the definition of MI_APG_INIT */ |
| 110 | * All pages' PP data bits are set to either 000 or 011 or 001, which means | 109 | #define MD_APG_INIT 0xdc000000 |
| 111 | * respectively RW for Supervisor and no access for User, or RO for | 110 | #define MD_APG_KUAP 0xde000000 |
| 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 | ||
| 128 | 111 | ||
| 129 | /* The effective page number register. When read, contains the information | 112 | /* The effective page number register. When read, contains the information |
| 130 | * about the last instruction TLB miss. When MD_RPN is written, bits in | 113 | * about the last instruction TLB miss. When MD_RPN is written, bits in |
| @@ -39,9 +39,9 @@ · 38 unmodified lines | |||
| 39 | * into the TLB. | 39 | * into the TLB. |
| 40 | */ | 40 | */ |
| 41 | #define _PAGE_GUARDED 0x0010 /* Copied to L1 G entry in DTLB */ | 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 | #define _PAGE_EXEC 0x0040 /* Copied to PP (bit 21) in ITLB */ | 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 | #define _PAGE_NA 0x0200 /* Supervisor NA, User no access */ | 46 | #define _PAGE_NA 0x0200 /* Supervisor NA, User no access */ |
| 47 | #define _PAGE_RO 0x0600 /* Supervisor RO, User no access */ | 47 | #define _PAGE_RO 0x0600 /* Supervisor RO, User no access */ |
| @@ -59,11 +59,12 @@ · 11 unmodified lines | |||
| 59 | 59 | ||
| 60 | #define _PMD_PRESENT 0x0001 | 60 | #define _PMD_PRESENT 0x0001 |
| 61 | #define _PMD_PRESENT_MASK _PMD_PRESENT | 61 | #define _PMD_PRESENT_MASK _PMD_PRESENT |
| 62 | #define _PMD_BAD 0x0fd0 | 62 | #define _PMD_BAD 0x0f90 |
| 63 | #define _PMD_PAGE_MASK 0x000c | 63 | #define _PMD_PAGE_MASK 0x000c |
| 64 | #define _PMD_PAGE_8M 0x000c | 64 | #define _PMD_PAGE_8M 0x000c |
| 65 | #define _PMD_PAGE_512K 0x0004 | 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 | #define _PTE_NONE_MASK 0 | 69 | #define _PTE_NONE_MASK 0 |
| 69 | 70 | ||
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | 6 | ||
| 7 | struct device; | 7 | struct device; |
| 8 | struct device_node; | 8 | struct device_node; |
| 9 | struct drmem_lmb; | ||
| 9 | 10 | ||
| 10 | #ifdef CONFIG_NUMA | 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 | return (nid < 0) ? 0 : nid; | 63 | return (nid < 0) ? 0 : nid; |
| 63 | } | 64 | } |
| 65 | |||
| 66 | int of_drconf_to_nid_single(struct drmem_lmb *lmb); | ||
| 67 | |||
| 64 | #else | 68 | #else |
| 65 | 69 | ||
| 66 | static inline int early_cpu_to_node(int cpu) { return 0; } | 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 | return 0; | 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; | 96 | #endif /* CONFIG_NUMA */ |
| 90 | int of_drconf_to_nid_single(struct drmem_lmb *lmb); | ||
| 91 | 97 | ||
| 92 | #if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR) | 98 | #if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR) |
| 93 | extern int find_and_online_cpu_nid(int cpu); | 99 | extern int find_and_online_cpu_nid(int cpu); |
| @@ -178,7 +178,7 @@ do { \ · 177 unmodified lines | |||
| 178 | * are no aliasing issues. | 178 | * are no aliasing issues. |
| 179 | */ | 179 | */ |
| 180 | #define __put_user_asm_goto(x, addr, label, op) \ | 180 | #define __put_user_asm_goto(x, addr, label, op) \ |
| 181 | asm volatile goto( \ | 181 | asm_volatile_goto( \ |
| 182 | "1: " op "%U1%X1 %0,%1 # put_user\n" \ | 182 | "1: " op "%U1%X1 %0,%1 # put_user\n" \ |
| 183 | EX_TABLE(1b, %l2) \ | 183 | EX_TABLE(1b, %l2) \ |
| 184 | : \ | 184 | : \ |
| @@ -191,7 +191,7 @@ do { \ · 6 unmodified lines | |||
| 191 | __put_user_asm_goto(x, ptr, label, "std") | 191 | __put_user_asm_goto(x, ptr, label, "std") |
| 192 | #else /* __powerpc64__ */ | 192 | #else /* __powerpc64__ */ |
| 193 | #define __put_user_asm2_goto(x, addr, label) \ | 193 | #define __put_user_asm2_goto(x, addr, label) \ |
| 194 | asm volatile goto( \ | 194 | asm_volatile_goto( \ |
| 195 | "1: stw%X1 %0, %1\n" \ | 195 | "1: stw%X1 %0, %1\n" \ |
| 196 | "2: stw%X1 %L0, %L1\n" \ | 196 | "2: stw%X1 %L0, %L1\n" \ |
| 197 | EX_TABLE(1b, %l2) \ | 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 | struct pci_io_addr_range *piar; | 265 | struct pci_io_addr_range *piar; |
| 266 | struct rb_node *n; | 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 | for (n = rb_first(&pci_io_addr_cache_root.rb_root); n; n = rb_next(n)) { | 270 | for (n = rb_first(&pci_io_addr_cache_root.rb_root); n; n = rb_next(n)) { |
| 270 | piar = rb_entry(n, struct pci_io_addr_range, rb_node); | 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 | (piar->flags & IORESOURCE_IO) ? "i/o" : "mem", | 274 | (piar->flags & IORESOURCE_IO) ? "i/o" : "mem", |
| 274 | &piar->addr_lo, &piar->addr_hi, pci_name(piar->pcidev)); | 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 | return 0; | 279 | return 0; |
| 279 | } | 280 | } |
| @@ -284,11 +284,7 @@ _ENTRY(saved_ksp_limit) · 283 unmodified lines | |||
| 284 | 284 | ||
| 285 | rlwimi r11, r10, 22, 20, 29 /* Compute PTE address */ | 285 | rlwimi r11, r10, 22, 20, 29 /* Compute PTE address */ |
| 286 | lwz r11, 0(r11) /* Get Linux PTE */ | 286 | lwz r11, 0(r11) /* Get Linux PTE */ |
| 287 | #ifdef CONFIG_SWAP | ||
| 288 | li r9, _PAGE_PRESENT | _PAGE_ACCESSED | 287 | li r9, _PAGE_PRESENT | _PAGE_ACCESSED |
| 289 | #else | ||
| 290 | li r9, _PAGE_PRESENT | ||
| 291 | #endif | ||
| 292 | andc. r9, r9, r11 /* Check permission */ | 288 | andc. r9, r9, r11 /* Check permission */ |
| 293 | bne 5f | 289 | bne 5f |
| 294 | 290 | ||
| @@ -369,11 +365,7 @@ _ENTRY(saved_ksp_limit) · 74 unmodified lines | |||
| 369 | 365 | ||
| 370 | rlwimi r11, r10, 22, 20, 29 /* Compute PTE address */ | 366 | rlwimi r11, r10, 22, 20, 29 /* Compute PTE address */ |
| 371 | lwz r11, 0(r11) /* Get Linux PTE */ | 367 | lwz r11, 0(r11) /* Get Linux PTE */ |
| 372 | #ifdef CONFIG_SWAP | ||
| 373 | li r9, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC | 368 | li r9, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC |
| 374 | #else | ||
| 375 | li r9, _PAGE_PRESENT | _PAGE_EXEC | ||
| 376 | #endif | ||
| 377 | andc. r9, r9, r11 /* Check permission */ | 369 | andc. r9, r9, r11 /* Check permission */ |
| 378 | bne 5f | 370 | bne 5f |
| 379 | 371 | ||
| @@ -202,9 +202,7 @@ SystemCall: · 201 unmodified lines | |||
| 202 | 202 | ||
| 203 | InstructionTLBMiss: | 203 | InstructionTLBMiss: |
| 204 | mtspr SPRN_SPRG_SCRATCH0, r10 | 204 | mtspr SPRN_SPRG_SCRATCH0, r10 |
| 205 | #if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP) || defined(CONFIG_HUGETLBFS) | ||
| 206 | mtspr SPRN_SPRG_SCRATCH1, r11 | 205 | mtspr SPRN_SPRG_SCRATCH1, r11 |
| 207 | #endif | ||
| 208 | 206 | ||
| 209 | /* If we are faulting a kernel address, we have to use the | 207 | /* If we are faulting a kernel address, we have to use the |
| 210 | * kernel page tables. | 208 | * kernel page tables. |
| @@ -224,25 +222,13 @@ InstructionTLBMiss: · 13 unmodified lines | |||
| 224 | 3: | 222 | 3: |
| 225 | mtcr r11 | 223 | mtcr r11 |
| 226 | #endif | 224 | #endif |
| 227 | #if defined(CONFIG_HUGETLBFS) || !defined(CONFIG_PIN_TLB_TEXT) | ||
| 228 | lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r10) /* Get level 1 entry */ | 225 | lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r10) /* Get level 1 entry */ |
| 229 | mtspr SPRN_MD_TWC, r11 | 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 | mfspr r10, SPRN_MD_TWC | 227 | mfspr r10, SPRN_MD_TWC |
| 236 | lwz r10, 0(r10) /* Get the pte */ | 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 | rlwimi r11, r10, 32 - 9, _PMD_PAGE_512K | 230 | rlwimi r11, r10, 32 - 9, _PMD_PAGE_512K |
| 239 | mtspr SPRN_MI_TWC, r11 | 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 | /* The Linux PTE won't go exactly into the MMU TLB. | 232 | /* The Linux PTE won't go exactly into the MMU TLB. |
| 247 | * Software indicator bits 20 and 23 must be clear. | 233 | * Software indicator bits 20 and 23 must be clear. |
| 248 | * Software indicator bits 22, 24, 25, 26, and 27 must be | 234 | * Software indicator bits 22, 24, 25, 26, and 27 must be |
| @@ -256,9 +242,7 @@ InstructionTLBMiss: · 7 unmodified lines | |||
| 256 | 242 | ||
| 257 | /* Restore registers */ | 243 | /* Restore registers */ |
| 258 | 0: mfspr r10, SPRN_SPRG_SCRATCH0 | 244 | 0: mfspr r10, SPRN_SPRG_SCRATCH0 |
| 259 | #if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP) || defined(CONFIG_HUGETLBFS) | ||
| 260 | mfspr r11, SPRN_SPRG_SCRATCH1 | 245 | mfspr r11, SPRN_SPRG_SCRATCH1 |
| 261 | #endif | ||
| 262 | rfi | 246 | rfi |
| 263 | patch_site 0b, patch__itlbmiss_exit_1 | 247 | patch_site 0b, patch__itlbmiss_exit_1 |
| 264 | 248 | ||
| @@ -268,9 +252,7 @@ InstructionTLBMiss: · 3 unmodified lines | |||
| 268 | addi r10, r10, 1 | 252 | addi r10, r10, 1 |
| 269 | stw r10, (itlb_miss_counter - PAGE_OFFSET)@l(0) | 253 | stw r10, (itlb_miss_counter - PAGE_OFFSET)@l(0) |
| 270 | mfspr r10, SPRN_SPRG_SCRATCH0 | 254 | mfspr r10, SPRN_SPRG_SCRATCH0 |
| 271 | #if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP) | ||
| 272 | mfspr r11, SPRN_SPRG_SCRATCH1 | 255 | mfspr r11, SPRN_SPRG_SCRATCH1 |
| 273 | #endif | ||
| 274 | rfi | 256 | rfi |
| 275 | #endif | 257 | #endif |
| 276 | 258 | ||
| @@ -297,30 +279,16 @@ DataStoreTLBMiss: · 20 unmodified lines | |||
| 297 | mfspr r10, SPRN_MD_TWC | 279 | mfspr r10, SPRN_MD_TWC |
| 298 | lwz r10, 0(r10) /* Get the pte */ | 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 | * It is bit 27 of both the Linux PTE and the TWC (at least | 283 | * It is bit 27 of both the Linux PTE and the TWC (at least |
| 302 | * I got that right :-). It will be better when we can put | 284 | * I got that right :-). It will be better when we can put |
| 303 | * this into the Linux pgd/pmd and load it in the operation | 285 | * this into the Linux pgd/pmd and load it in the operation |
| 304 | * above. | 286 | * above. |
| 305 | */ | 287 | */ |
| 306 | rlwimi r11, r10, 0, _PAGE_GUARDED | 288 | rlwimi r11, r10, 0, _PAGE_GUARDED | _PAGE_ACCESSED |
| 307 | rlwimi r11, r10, 32 - 9, _PMD_PAGE_512K | 289 | rlwimi r11, r10, 32 - 9, _PMD_PAGE_512K |
| 308 | mtspr SPRN_MD_TWC, r11 | 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 | /* The Linux PTE won't go exactly into the MMU TLB. | 292 | /* The Linux PTE won't go exactly into the MMU TLB. |
| 325 | * Software indicator bits 24, 25, 26, and 27 must be | 293 | * Software indicator bits 24, 25, 26, and 27 must be |
| 326 | * set. All other Linux PTE bits control the behavior | 294 | * set. All other Linux PTE bits control the behavior |
| @@ -711,7 +679,7 @@ initial_mmu: · 384 unmodified lines | |||
| 711 | li r9, 4 /* up to 4 pages of 8M */ | 679 | li r9, 4 /* up to 4 pages of 8M */ |
| 712 | mtctr r9 | 680 | mtctr r9 |
| 713 | lis r9, KERNELBASE@h /* Create vaddr for TLB */ | 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 | li r11, MI_BOOTINIT /* Create RPN for address 0 */ | 683 | li r11, MI_BOOTINIT /* Create RPN for address 0 */ |
| 716 | 1: | 684 | 1: |
| 717 | mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */ | 685 | mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */ |
| @@ -775,7 +743,7 @@ _GLOBAL(mmu_pin_tlb) · 57 unmodified lines | |||
| 775 | #ifdef CONFIG_PIN_TLB_TEXT | 743 | #ifdef CONFIG_PIN_TLB_TEXT |
| 776 | LOAD_REG_IMMEDIATE(r5, 28 << 8) | 744 | LOAD_REG_IMMEDIATE(r5, 28 << 8) |
| 777 | LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET) | 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 | LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_RO | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT) | 747 | LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_RO | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT) |
| 780 | LOAD_REG_ADDR(r9, _sinittext) | 748 | LOAD_REG_ADDR(r9, _sinittext) |
| 781 | li r0, 4 | 749 | li r0, 4 |
| @@ -797,7 +765,7 @@ _GLOBAL(mmu_pin_tlb) · 15 unmodified lines | |||
| 797 | LOAD_REG_IMMEDIATE(r5, 28 << 8 | MD_TWAM) | 765 | LOAD_REG_IMMEDIATE(r5, 28 << 8 | MD_TWAM) |
| 798 | #ifdef CONFIG_PIN_TLB_DATA | 766 | #ifdef CONFIG_PIN_TLB_DATA |
| 799 | LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET) | 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 | #ifdef CONFIG_PIN_TLB_IMMR | 769 | #ifdef CONFIG_PIN_TLB_IMMR |
| 802 | li r0, 3 | 770 | li r0, 3 |
| 803 | #else | 771 | #else |
| @@ -834,7 +802,7 @@ _GLOBAL(mmu_pin_tlb) · 30 unmodified lines | |||
| 834 | #endif | 802 | #endif |
| 835 | #ifdef CONFIG_PIN_TLB_IMMR | 803 | #ifdef CONFIG_PIN_TLB_IMMR |
| 836 | LOAD_REG_IMMEDIATE(r0, VIRT_IMMR_BASE | MD_EVALID) | 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 | mfspr r8, SPRN_IMMR | 806 | mfspr r8, SPRN_IMMR |
| 839 | rlwinm r8, r8, 0, 0xfff80000 | 807 | rlwinm r8, r8, 0, 0xfff80000 |
| 840 | ori r8, r8, 0xf0 | _PAGE_DIRTY | _PAGE_SPS | _PAGE_SH | \ | 808 | ori r8, r8, 0xf0 | _PAGE_DIRTY | _PAGE_SPS | _PAGE_SH | \ |
| @@ -457,11 +457,7 @@ InstructionTLBMiss: · 456 unmodified lines | |||
| 457 | cmplw 0,r1,r3 | 457 | cmplw 0,r1,r3 |
| 458 | #endif | 458 | #endif |
| 459 | mfspr r2, SPRN_SPRG_PGDIR | 459 | mfspr r2, SPRN_SPRG_PGDIR |
| 460 | #ifdef CONFIG_SWAP | ||
| 461 | li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC | 460 | li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC |
| 462 | #else | ||
| 463 | li r1,_PAGE_PRESENT | _PAGE_EXEC | ||
| 464 | #endif | ||
| 465 | #if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC) | 461 | #if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC) |
| 466 | bgt- 112f | 462 | bgt- 112f |
| 467 | lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ | 463 | lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ |
| @@ -523,11 +519,7 @@ DataLoadTLBMiss: · 55 unmodified lines | |||
| 523 | lis r1, TASK_SIZE@h /* check if kernel address */ | 519 | lis r1, TASK_SIZE@h /* check if kernel address */ |
| 524 | cmplw 0,r1,r3 | 520 | cmplw 0,r1,r3 |
| 525 | mfspr r2, SPRN_SPRG_PGDIR | 521 | mfspr r2, SPRN_SPRG_PGDIR |
| 526 | #ifdef CONFIG_SWAP | ||
| 527 | li r1, _PAGE_PRESENT | _PAGE_ACCESSED | 522 | li r1, _PAGE_PRESENT | _PAGE_ACCESSED |
| 528 | #else | ||
| 529 | li r1, _PAGE_PRESENT | ||
| 530 | #endif | ||
| 531 | bgt- 112f | 523 | bgt- 112f |
| 532 | lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ | 524 | lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ |
| 533 | addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ | 525 | addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ |
| @@ -603,11 +595,7 @@ DataStoreTLBMiss: · 69 unmodified lines | |||
| 603 | lis r1, TASK_SIZE@h /* check if kernel address */ | 595 | lis r1, TASK_SIZE@h /* check if kernel address */ |
| 604 | cmplw 0,r1,r3 | 596 | cmplw 0,r1,r3 |
| 605 | mfspr r2, SPRN_SPRG_PGDIR | 597 | mfspr r2, SPRN_SPRG_PGDIR |
| 606 | #ifdef CONFIG_SWAP | ||
| 607 | li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED | 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 | bgt- 112f | 599 | bgt- 112f |
| 612 | lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ | 600 | lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ |
| 613 | addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ | 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 | /* Activate a secondary processor. */ | 1393 | /* Activate a secondary processor. */ |
| 1394 | void start_secondary(void *unused) | 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 | mmgrab(&init_mm); | 1398 | mmgrab(&init_mm); |
| 1399 | current->active_mm = &init_mm; | 1399 | current->active_mm = &init_mm; |
| 1400 | 1400 | ||
| 1401 | smp_store_cpu_info(cpu); | 1401 | smp_store_cpu_info(cpu); |
| 1402 | set_dec(tb_ticks_per_jiffy); | 1402 | set_dec(tb_ticks_per_jiffy); |
| 1403 | rcu_cpu_starting(cpu); | ||
| 1403 | preempt_disable(); | 1404 | preempt_disable(); |
| 1404 | cpu_callin_map[cpu] = 1; | 1405 | cpu_callin_map[cpu] = 1; |
| 1405 | 1406 | ||
| @@ -476,7 +476,7 @@ do { \ · 475 unmodified lines | |||
| 476 | do { \ | 476 | do { \ |
| 477 | long __kr_err; \ | 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 | if (unlikely(__kr_err)) \ | 480 | if (unlikely(__kr_err)) \ |
| 481 | goto err_label; \ | 481 | goto err_label; \ |
| 482 | } while (0) | 482 | } while (0) |
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | /* | 2 | /* |
| 3 | * Copyright (C) 2013 Linaro Limited | 3 | * Copyright (C) 2013 Linaro Limited |
| 4 | * Author: AKASHI Takahiro <takahiro.akashi@linaro.org> | 4 | * Author: AKASHI Takahiro <takahiro.akashi@linaro.org> |
| @@ -35,12 +35,17 @@ ENTRY(_start) · 34 unmodified lines | |||
| 35 | .word 0 | 35 | .word 0 |
| 36 | #endif | 36 | #endif |
| 37 | .balign 8 | 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 | #if __riscv_xlen == 64 | 42 | #if __riscv_xlen == 64 |
| 39 | /* Image load offset(2MB) from start of RAM */ | 43 | /* Image load offset(2MB) from start of RAM */ |
| 40 | .dword 0x200000 | 44 | .dword 0x200000 |
| 41 | #else | 45 | #else |
| 42 | /* Image load offset(4MB) from start of RAM */ | 46 | /* Image load offset(4MB) from start of RAM */ |
| 43 | .dword 0x400000 | 47 | .dword 0x400000 |
| 48 | #endif | ||
| 44 | #endif | 49 | #endif |
| 45 | /* Effective size of kernel image */ | 50 | /* Effective size of kernel image */ |
| 46 | .dword _end - _start | 51 | .dword _end - _start |
| @@ -1,3 +1,4 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | vdso.lds | 2 | vdso.lds |
| 3 | *.tmp | 3 | *.tmp |
| 4 | vdso-syms.S | ||
| @@ -43,19 +43,14 @@ $(obj)/vdso.o: $(obj)/vdso.so · 42 unmodified lines | |||
| 43 | SYSCFLAGS_vdso.so.dbg = $(c_flags) | 43 | SYSCFLAGS_vdso.so.dbg = $(c_flags) |
| 44 | $(obj)/vdso.so.dbg: $(src)/vdso.lds $(obj-vdso) FORCE | 44 | $(obj)/vdso.so.dbg: $(src)/vdso.lds $(obj-vdso) FORCE |
| 45 | $(call if_changed,vdsold) | 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 | # We also create a special relocatable object that should mirror the symbol | 49 | # We also create a special relocatable object that should mirror the symbol |
| 48 | # table and layout of the linked DSO. With ld --just-symbols we can then | 50 | # table and layout of the linked DSO. With ld --just-symbols we can then |
| 49 | # refer to these symbols in the kernel code rather than hand-coded addresses. | 51 | # refer to these symbols in the kernel code rather than hand-coded addresses. |
| 50 | 52 | $(obj)/vdso-syms.S: $(obj)/vdso.so FORCE | |
| 51 | SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \ | 53 | $(call if_changed,so2s) |
| 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) | ||
| 59 | 54 | ||
| 60 | # strip rule for the .so file | 55 | # strip rule for the .so file |
| 61 | $(obj)/%.so: OBJCOPYFLAGS := -S | 56 | $(obj)/%.so: OBJCOPYFLAGS := -S |
| @@ -73,6 +68,11 @@ quiet_cmd_vdsold = VDSOLD $@ · 11 unmodified lines | |||
| 73 | $(patsubst %, -G __vdso_%, $(vdso-syms)) $@.tmp $@ && \ | 68 | $(patsubst %, -G __vdso_%, $(vdso-syms)) $@.tmp $@ && \ |
| 74 | rm $@.tmp | 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 | # install commands for the unstripped file | 76 | # install commands for the unstripped file |
| 77 | quiet_cmd_vdso_install = INSTALL $@ | 77 | quiet_cmd_vdso_install = INSTALL $@ |
| 78 | cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@ | 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 | pmd_t *pmd, *pmd_k; | 86 | pmd_t *pmd, *pmd_k; |
| 87 | pte_t *pte_k; | 87 | pte_t *pte_k; |
| 88 | int index; | 88 | int index; |
| 89 | unsigned long pfn; | ||
| 89 | 90 | ||
| 90 | /* User mode accesses just cause a SIGSEGV */ | 91 | /* User mode accesses just cause a SIGSEGV */ |
| 91 | if (user_mode(regs)) | 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 | * of a task switch. | 101 | * of a task switch. |
| 101 | */ | 102 | */ |
| 102 | index = pgd_index(addr); | 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 | pgd_k = init_mm.pgd + index; | 106 | pgd_k = init_mm.pgd + index; |
| 105 | 107 | ||
| 106 | if (!pgd_present(*pgd_k)) { | 108 | if (!pgd_present(*pgd_k)) { |
| @@ -154,9 +154,8 @@ disable: · 153 unmodified lines | |||
| 154 | 154 | ||
| 155 | void __init setup_bootmem(void) | 155 | void __init setup_bootmem(void) |
| 156 | { | 156 | { |
| 157 | phys_addr_t mem_size = 0; | 157 | phys_addr_t mem_start = 0; |
| 158 | phys_addr_t total_mem = 0; | 158 | phys_addr_t start, end = 0; |
| 159 | phys_addr_t mem_start, start, end = 0; | ||
| 160 | phys_addr_t vmlinux_end = __pa_symbol(&_end); | 159 | phys_addr_t vmlinux_end = __pa_symbol(&_end); |
| 161 | phys_addr_t vmlinux_start = __pa_symbol(&_start); | 160 | phys_addr_t vmlinux_start = __pa_symbol(&_start); |
| 162 | u64 i; | 161 | u64 i; |
| @@ -164,21 +163,18 @@ void __init setup_bootmem(void) · 1 unmodified line | |||
| 164 | /* Find the memory region containing the kernel */ | 163 | /* Find the memory region containing the kernel */ |
| 165 | for_each_mem_range(i, &start, &end) { | 164 | for_each_mem_range(i, &start, &end) { |
| 166 | phys_addr_t size = end - start; | 165 | phys_addr_t size = end - start; |
| 167 | if (!total_mem) | 166 | if (!mem_start) |
| 168 | mem_start = start; | 167 | mem_start = start; |
| 169 | if (start <= vmlinux_start && vmlinux_end <= end) | 168 | if (start <= vmlinux_start && vmlinux_end <= end) |
| 170 | BUG_ON(size == 0); | 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 | 173 | * The maximal physical memory size is -PAGE_OFFSET. |
| 176 | * end of region | 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); | 177 | memblock_enforce_memory_limit(mem_start - PAGE_OFFSET); |
| 179 | if (mem_start + mem_size < end) | ||
| 180 | memblock_remove(mem_start + mem_size, | ||
| 181 | end - mem_start - mem_size); | ||
| 182 | 178 | ||
| 183 | /* Reserve from the start of the kernel to the end of the kernel */ | 179 | /* Reserve from the start of the kernel to the end of the kernel */ |
| 184 | memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start); | 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 | #define NUM_EARLY_PMDS (1UL + MAX_EARLY_MAPPING_SIZE / PGDIR_SIZE) | 293 | #define NUM_EARLY_PMDS (1UL + MAX_EARLY_MAPPING_SIZE / PGDIR_SIZE) |
| 298 | #endif | 294 | #endif |
| 299 | pmd_t early_pmd[PTRS_PER_PMD * NUM_EARLY_PMDS] __initdata __aligned(PAGE_SIZE); | 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 | static pmd_t *__init get_pmd_virt_early(phys_addr_t pa) | 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 | load_pa + (va - PAGE_OFFSET), | 491 | load_pa + (va - PAGE_OFFSET), |
| 495 | map_size, PAGE_KERNEL_EXEC); | 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 | /* Create two consecutive PGD mappings for FDT early scan */ | 506 | /* Create two consecutive PGD mappings for FDT early scan */ |
| 498 | pa = dtb_pa & ~(PGDIR_SIZE - 1); | 507 | pa = dtb_pa & ~(PGDIR_SIZE - 1); |
| 499 | create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA, | 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 | create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA + PGDIR_SIZE, | 510 | create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA + PGDIR_SIZE, |
| 502 | pa + PGDIR_SIZE, PGDIR_SIZE, PAGE_KERNEL); | 511 | pa + PGDIR_SIZE, PGDIR_SIZE, PAGE_KERNEL); |
| 503 | dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PGDIR_SIZE - 1)); | 512 | dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PGDIR_SIZE - 1)); |
| 513 | #endif | ||
| 504 | dtb_early_pa = dtb_pa; | 514 | dtb_early_pa = dtb_pa; |
| 505 | 515 | ||
| 506 | /* | 516 | /* |
| @@ -93,9 +93,10 @@ CONFIG_CLEANCACHE=y · 92 unmodified lines | |||
| 93 | CONFIG_FRONTSWAP=y | 93 | CONFIG_FRONTSWAP=y |
| 94 | CONFIG_CMA_DEBUG=y | 94 | CONFIG_CMA_DEBUG=y |
| 95 | CONFIG_CMA_DEBUGFS=y | 95 | CONFIG_CMA_DEBUGFS=y |
| 96 | CONFIG_CMA_AREAS=7 | ||
| 96 | CONFIG_MEM_SOFT_DIRTY=y | 97 | CONFIG_MEM_SOFT_DIRTY=y |
| 97 | CONFIG_ZSWAP=y | 98 | CONFIG_ZSWAP=y |
| 98 | CONFIG_ZSMALLOC=m | 99 | CONFIG_ZSMALLOC=y |
| 99 | CONFIG_ZSMALLOC_STAT=y | 100 | CONFIG_ZSMALLOC_STAT=y |
| 100 | CONFIG_DEFERRED_STRUCT_PAGE_INIT=y | 101 | CONFIG_DEFERRED_STRUCT_PAGE_INIT=y |
| 101 | CONFIG_IDLE_PAGE_TRACKING=y | 102 | CONFIG_IDLE_PAGE_TRACKING=y |
| @@ -378,7 +379,6 @@ CONFIG_NETLINK_DIAG=m · 276 unmodified lines | |||
| 378 | CONFIG_CGROUP_NET_PRIO=y | 379 | CONFIG_CGROUP_NET_PRIO=y |
| 379 | CONFIG_BPF_JIT=y | 380 | CONFIG_BPF_JIT=y |
| 380 | CONFIG_NET_PKTGEN=m | 381 | CONFIG_NET_PKTGEN=m |
| 381 | # CONFIG_NET_DROP_MONITOR is not set | ||
| 382 | CONFIG_PCI=y | 382 | CONFIG_PCI=y |
| 383 | # CONFIG_PCIEASPM is not set | 383 | # CONFIG_PCIEASPM is not set |
| 384 | CONFIG_PCI_DEBUG=y | 384 | CONFIG_PCI_DEBUG=y |
| @@ -386,7 +386,7 @@ CONFIG_HOTPLUG_PCI=y · 1 unmodified line | |||
| 386 | CONFIG_HOTPLUG_PCI_S390=y | 386 | CONFIG_HOTPLUG_PCI_S390=y |
| 387 | CONFIG_DEVTMPFS=y | 387 | CONFIG_DEVTMPFS=y |
| 388 | CONFIG_CONNECTOR=y | 388 | CONFIG_CONNECTOR=y |
| 389 | CONFIG_ZRAM=m | 389 | CONFIG_ZRAM=y |
| 390 | CONFIG_BLK_DEV_LOOP=m | 390 | CONFIG_BLK_DEV_LOOP=m |
| 391 | CONFIG_BLK_DEV_CRYPTOLOOP=m | 391 | CONFIG_BLK_DEV_CRYPTOLOOP=m |
| 392 | CONFIG_BLK_DEV_DRBD=m | 392 | CONFIG_BLK_DEV_DRBD=m |
| @@ -689,6 +689,7 @@ CONFIG_CRYPTO_TEST=m · 296 unmodified lines | |||
| 689 | CONFIG_CRYPTO_DH=m | 689 | CONFIG_CRYPTO_DH=m |
| 690 | CONFIG_CRYPTO_ECDH=m | 690 | CONFIG_CRYPTO_ECDH=m |
| 691 | CONFIG_CRYPTO_ECRDSA=m | 691 | CONFIG_CRYPTO_ECRDSA=m |
| 692 | CONFIG_CRYPTO_SM2=m | ||
| 692 | CONFIG_CRYPTO_CURVE25519=m | 693 | CONFIG_CRYPTO_CURVE25519=m |
| 693 | CONFIG_CRYPTO_GCM=y | 694 | CONFIG_CRYPTO_GCM=y |
| 694 | CONFIG_CRYPTO_CHACHA20POLY1305=m | 695 | CONFIG_CRYPTO_CHACHA20POLY1305=m |
| @@ -709,7 +710,6 @@ CONFIG_CRYPTO_RMD160=m · 14 unmodified lines | |||
| 709 | CONFIG_CRYPTO_RMD256=m | 710 | CONFIG_CRYPTO_RMD256=m |
| 710 | CONFIG_CRYPTO_RMD320=m | 711 | CONFIG_CRYPTO_RMD320=m |
| 711 | CONFIG_CRYPTO_SHA3=m | 712 | CONFIG_CRYPTO_SHA3=m |
| 712 | CONFIG_CRYPTO_SM3=m | ||
| 713 | CONFIG_CRYPTO_TGR192=m | 713 | CONFIG_CRYPTO_TGR192=m |
| 714 | CONFIG_CRYPTO_WP512=m | 714 | CONFIG_CRYPTO_WP512=m |
| 715 | CONFIG_CRYPTO_AES_TI=m | 715 | CONFIG_CRYPTO_AES_TI=m |
| @@ -753,6 +753,7 @@ CONFIG_CRYPTO_DES_S390=m · 37 unmodified lines | |||
| 753 | CONFIG_CRYPTO_AES_S390=m | 753 | CONFIG_CRYPTO_AES_S390=m |
| 754 | CONFIG_CRYPTO_GHASH_S390=m | 754 | CONFIG_CRYPTO_GHASH_S390=m |
| 755 | CONFIG_CRYPTO_CRC32_S390=y | 755 | CONFIG_CRYPTO_CRC32_S390=y |
| 756 | CONFIG_CRYPTO_DEV_VIRTIO=m | ||
| 756 | CONFIG_CORDIC=m | 757 | CONFIG_CORDIC=m |
| 757 | CONFIG_CRC32_SELFTEST=y | 758 | CONFIG_CRC32_SELFTEST=y |
| 758 | CONFIG_CRC4=m | 759 | CONFIG_CRC4=m |
| @@ -829,6 +830,7 @@ CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m · 70 unmodified lines | |||
| 829 | CONFIG_FAULT_INJECTION=y | 830 | CONFIG_FAULT_INJECTION=y |
| 830 | CONFIG_FAILSLAB=y | 831 | CONFIG_FAILSLAB=y |
| 831 | CONFIG_FAIL_PAGE_ALLOC=y | 832 | CONFIG_FAIL_PAGE_ALLOC=y |
| 833 | CONFIG_FAULT_INJECTION_USERCOPY=y | ||
| 832 | CONFIG_FAIL_MAKE_REQUEST=y | 834 | CONFIG_FAIL_MAKE_REQUEST=y |
| 833 | CONFIG_FAIL_IO_TIMEOUT=y | 835 | CONFIG_FAIL_IO_TIMEOUT=y |
| 834 | CONFIG_FAIL_FUTEX=y | 836 | CONFIG_FAIL_FUTEX=y |
| @@ -87,9 +87,10 @@ CONFIG_KSM=y · 86 unmodified lines | |||
| 87 | CONFIG_TRANSPARENT_HUGEPAGE=y | 87 | CONFIG_TRANSPARENT_HUGEPAGE=y |
| 88 | CONFIG_CLEANCACHE=y | 88 | CONFIG_CLEANCACHE=y |
| 89 | CONFIG_FRONTSWAP=y | 89 | CONFIG_FRONTSWAP=y |
| 90 | CONFIG_CMA_AREAS=7 | ||
| 90 | CONFIG_MEM_SOFT_DIRTY=y | 91 | CONFIG_MEM_SOFT_DIRTY=y |
| 91 | CONFIG_ZSWAP=y | 92 | CONFIG_ZSWAP=y |
| 92 | CONFIG_ZSMALLOC=m | 93 | CONFIG_ZSMALLOC=y |
| 93 | CONFIG_ZSMALLOC_STAT=y | 94 | CONFIG_ZSMALLOC_STAT=y |
| 94 | CONFIG_DEFERRED_STRUCT_PAGE_INIT=y | 95 | CONFIG_DEFERRED_STRUCT_PAGE_INIT=y |
| 95 | CONFIG_IDLE_PAGE_TRACKING=y | 96 | CONFIG_IDLE_PAGE_TRACKING=y |
| @@ -371,7 +372,6 @@ CONFIG_NETLINK_DIAG=m · 275 unmodified lines | |||
| 371 | CONFIG_CGROUP_NET_PRIO=y | 372 | CONFIG_CGROUP_NET_PRIO=y |
| 372 | CONFIG_BPF_JIT=y | 373 | CONFIG_BPF_JIT=y |
| 373 | CONFIG_NET_PKTGEN=m | 374 | CONFIG_NET_PKTGEN=m |
| 374 | # CONFIG_NET_DROP_MONITOR is not set | ||
| 375 | CONFIG_PCI=y | 375 | CONFIG_PCI=y |
| 376 | # CONFIG_PCIEASPM is not set | 376 | # CONFIG_PCIEASPM is not set |
| 377 | CONFIG_HOTPLUG_PCI=y | 377 | CONFIG_HOTPLUG_PCI=y |
| @@ -379,7 +379,7 @@ CONFIG_HOTPLUG_PCI_S390=y · 1 unmodified line | |||
| 379 | CONFIG_UEVENT_HELPER=y | 379 | CONFIG_UEVENT_HELPER=y |
| 380 | CONFIG_DEVTMPFS=y | 380 | CONFIG_DEVTMPFS=y |
| 381 | CONFIG_CONNECTOR=y | 381 | CONFIG_CONNECTOR=y |
| 382 | CONFIG_ZRAM=m | 382 | CONFIG_ZRAM=y |
| 383 | CONFIG_BLK_DEV_LOOP=m | 383 | CONFIG_BLK_DEV_LOOP=m |
| 384 | CONFIG_BLK_DEV_CRYPTOLOOP=m | 384 | CONFIG_BLK_DEV_CRYPTOLOOP=m |
| 385 | CONFIG_BLK_DEV_DRBD=m | 385 | CONFIG_BLK_DEV_DRBD=m |
| @@ -680,6 +680,7 @@ CONFIG_CRYPTO_TEST=m · 294 unmodified lines | |||
| 680 | CONFIG_CRYPTO_DH=m | 680 | CONFIG_CRYPTO_DH=m |
| 681 | CONFIG_CRYPTO_ECDH=m | 681 | CONFIG_CRYPTO_ECDH=m |
| 682 | CONFIG_CRYPTO_ECRDSA=m | 682 | CONFIG_CRYPTO_ECRDSA=m |
| 683 | CONFIG_CRYPTO_SM2=m | ||
| 683 | CONFIG_CRYPTO_CURVE25519=m | 684 | CONFIG_CRYPTO_CURVE25519=m |
| 684 | CONFIG_CRYPTO_GCM=y | 685 | CONFIG_CRYPTO_GCM=y |
| 685 | CONFIG_CRYPTO_CHACHA20POLY1305=m | 686 | CONFIG_CRYPTO_CHACHA20POLY1305=m |
| @@ -701,7 +702,6 @@ CONFIG_CRYPTO_RMD160=m · 15 unmodified lines | |||
| 701 | CONFIG_CRYPTO_RMD256=m | 702 | CONFIG_CRYPTO_RMD256=m |
| 702 | CONFIG_CRYPTO_RMD320=m | 703 | CONFIG_CRYPTO_RMD320=m |
| 703 | CONFIG_CRYPTO_SHA3=m | 704 | CONFIG_CRYPTO_SHA3=m |
| 704 | CONFIG_CRYPTO_SM3=m | ||
| 705 | CONFIG_CRYPTO_TGR192=m | 705 | CONFIG_CRYPTO_TGR192=m |
| 706 | CONFIG_CRYPTO_WP512=m | 706 | CONFIG_CRYPTO_WP512=m |
| 707 | CONFIG_CRYPTO_AES_TI=m | 707 | CONFIG_CRYPTO_AES_TI=m |
| @@ -745,6 +745,7 @@ CONFIG_CRYPTO_DES_S390=m · 37 unmodified lines | |||
| 745 | CONFIG_CRYPTO_AES_S390=m | 745 | CONFIG_CRYPTO_AES_S390=m |
| 746 | CONFIG_CRYPTO_GHASH_S390=m | 746 | CONFIG_CRYPTO_GHASH_S390=m |
| 747 | CONFIG_CRYPTO_CRC32_S390=y | 747 | CONFIG_CRYPTO_CRC32_S390=y |
| 748 | CONFIG_CRYPTO_DEV_VIRTIO=m | ||
| 748 | CONFIG_CORDIC=m | 749 | CONFIG_CORDIC=m |
| 749 | CONFIG_PRIME_NUMBERS=m | 750 | CONFIG_PRIME_NUMBERS=m |
| 750 | CONFIG_CRC4=m | 751 | CONFIG_CRC4=m |
| @@ -17,11 +17,11 @@ CONFIG_HZ_100=y · 16 unmodified lines | |||
| 17 | # CONFIG_CHSC_SCH is not set | 17 | # CONFIG_CHSC_SCH is not set |
| 18 | # CONFIG_SCM_BUS is not set | 18 | # CONFIG_SCM_BUS is not set |
| 19 | CONFIG_CRASH_DUMP=y | 19 | CONFIG_CRASH_DUMP=y |
| 20 | # CONFIG_SECCOMP is not set | ||
| 21 | # CONFIG_PFAULT is not set | 20 | # CONFIG_PFAULT is not set |
| 22 | # CONFIG_S390_HYPFS_FS is not set | 21 | # CONFIG_S390_HYPFS_FS is not set |
| 23 | # CONFIG_VIRTUALIZATION is not set | 22 | # CONFIG_VIRTUALIZATION is not set |
| 24 | # CONFIG_S390_GUEST is not set | 23 | # CONFIG_S390_GUEST is not set |
| 24 | # CONFIG_SECCOMP is not set | ||
| 25 | CONFIG_PARTITION_ADVANCED=y | 25 | CONFIG_PARTITION_ADVANCED=y |
| 26 | CONFIG_IBM_PARTITION=y | 26 | CONFIG_IBM_PARTITION=y |
| 27 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | 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 | return !!(pud_val(pud) & _REGION3_ENTRY_LARGE); | 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 | #define pmd_leaf pmd_large | 695 | #define pmd_leaf pmd_large |
| 706 | static inline int pmd_large(pmd_t pmd) | 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 | return pmd_val(pmd) == _SEGMENT_ENTRY_EMPTY; | 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 | #define pmd_write pmd_write | 740 | #define pmd_write pmd_write |
| 761 | static inline int pmd_write(pmd_t pmd) | 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 | #define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) | 1218 | #define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) |
| 1239 | #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) | 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 | #define p4d_deref(pud) (p4d_val(pud) & _REGION_ENTRY_ORIGIN) | 1221 | #define p4d_deref(pud) (p4d_val(pud) & _REGION_ENTRY_ORIGIN) |
| 1244 | #define pgd_deref(pgd) (pgd_val(pgd) & _REGION_ENTRY_ORIGIN) | 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 | * The pgd_offset function *always* adds the index for the top-level | 1255 | * The pgd_offset function *always* adds the index for the top-level |
| 1248 | * region/segment table. This is done to get a sequence like the | 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 | BLANK(); | 61 | BLANK(); |
| 62 | OFFSET(__VDSO_GETCPU_VAL, vdso_per_cpu_data, getcpu_val); | 62 | OFFSET(__VDSO_GETCPU_VAL, vdso_per_cpu_data, getcpu_val); |
| 63 | BLANK(); | 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 | /* idle data offsets */ | 64 | /* idle data offsets */ |
| 73 | OFFSET(__CLOCK_IDLE_ENTER, s390_idle_data, clock_idle_enter); | 65 | OFFSET(__CLOCK_IDLE_ENTER, s390_idle_data, clock_idle_enter); |
| 74 | OFFSET(__CLOCK_IDLE_EXIT, s390_idle_data, clock_idle_exit); | 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 | static void smp_init_secondary(void) | 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 | S390_lowcore.last_update_clock = get_tod_clock(); | 860 | S390_lowcore.last_update_clock = get_tod_clock(); |
| 861 | restore_access_regs(S390_lowcore.access_regs_save_area); | 861 | restore_access_regs(S390_lowcore.access_regs_save_area); |
| 862 | set_cpu_flag(CIF_ASCE_PRIMARY); | 862 | set_cpu_flag(CIF_ASCE_PRIMARY); |
| 863 | set_cpu_flag(CIF_ASCE_SECONDARY); | 863 | set_cpu_flag(CIF_ASCE_SECONDARY); |
| 864 | cpu_init(); | 864 | cpu_init(); |
| 865 | rcu_cpu_starting(cpu); | ||
| 865 | preempt_disable(); | 866 | preempt_disable(); |
| 866 | init_cpu_timer(); | 867 | init_cpu_timer(); |
| 867 | vtime_init(); | 868 | vtime_init(); |
| @@ -101,6 +101,10 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) · 100 unmodified lines | |||
| 101 | if (ret) | 101 | if (ret) |
| 102 | break; | 102 | break; |
| 103 | 103 | ||
| 104 | /* the PCI function will be scanned once function 0 appears */ | ||
| 105 | if (!zdev->zbus->bus) | ||
| 106 | break; | ||
| 107 | |||
| 104 | pdev = pci_scan_single_device(zdev->zbus->bus, zdev->devfn); | 108 | pdev = pci_scan_single_device(zdev->zbus->bus, zdev->devfn); |
| 105 | if (!pdev) | 109 | if (!pdev) |
| 106 | break; | 110 | break; |
| @@ -164,6 +164,7 @@ void initialize_identity_maps(void *rmode) · 163 unmodified lines | |||
| 164 | add_identity_map(cmdline, cmdline + COMMAND_LINE_SIZE); | 164 | add_identity_map(cmdline, cmdline + COMMAND_LINE_SIZE); |
| 165 | 165 | ||
| 166 | /* Load the new page-table. */ | 166 | /* Load the new page-table. */ |
| 167 | sev_verify_cbit(top_level_pgt); | ||
| 167 | write_cr3(top_level_pgt); | 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 | SYM_FUNC_END(get_sev_encryption_bit) | 68 | SYM_FUNC_END(get_sev_encryption_bit) |
| 69 | 69 | ||
| 70 | .code64 | 70 | .code64 |
| 71 | |||
| 72 | #include "../../kernel/sev_verify_cbit.S" | ||
| 73 | |||
| 71 | SYM_FUNC_START(set_sev_encryption_mask) | 74 | SYM_FUNC_START(set_sev_encryption_mask) |
| 72 | #ifdef CONFIG_AMD_MEM_ENCRYPT | 75 | #ifdef CONFIG_AMD_MEM_ENCRYPT |
| 73 | push %rbp | 76 | push %rbp |
| @@ -81,6 +84,19 @@ SYM_FUNC_START(set_sev_encryption_mask) · 7 unmodified lines | |||
| 81 | 84 | ||
| 82 | bts %rax, sme_me_mask(%rip) /* Create the encryption mask */ | 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 | .Lno_sev_mask: | 100 | .Lno_sev_mask: |
| 85 | movq %rbp, %rsp /* Restore original stack pointer */ | 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 | #ifdef CONFIG_AMD_MEM_ENCRYPT | 113 | #ifdef CONFIG_AMD_MEM_ENCRYPT |
| 98 | .balign 8 | 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 | #endif | 118 | #endif |
| @@ -159,4 +159,6 @@ void boot_page_fault(void); · 158 unmodified lines | |||
| 159 | void boot_stage1_vc(void); | 159 | void boot_stage1_vc(void); |
| 160 | void boot_stage2_vc(void); | 160 | void boot_stage2_vc(void); |
| 161 | 161 | ||
| 162 | unsigned long sev_verify_cbit(unsigned long cr3); | ||
| 163 | |||
| 162 | #endif /* BOOT_COMPRESSED_MISC_H */ | 164 | #endif /* BOOT_COMPRESSED_MISC_H */ |
| @@ -273,11 +273,15 @@ void __init hv_apic_init(void) · 272 unmodified lines | |||
| 273 | pr_info("Hyper-V: Using enlightened APIC (%s mode)", | 273 | pr_info("Hyper-V: Using enlightened APIC (%s mode)", |
| 274 | x2apic_enabled() ? "x2apic" : "xapic"); | 274 | x2apic_enabled() ? "x2apic" : "xapic"); |
| 275 | /* | 275 | /* |
| 276 | * With x2apic, architectural x2apic MSRs are equivalent to the | 276 | * When in x2apic mode, don't use the Hyper-V specific APIC |
| 277 | * respective synthetic MSRs, so there's no need to override | 277 | * accessors since the field layout in the ICR register is |
| 278 | * the apic accessors. The only exception is | 278 | * different in x2apic mode. Furthermore, the architectural |
| 279 | * hv_apic_eoi_write, because it benefits from lazy EOI when | 279 | * x2apic MSRs function just as well as the Hyper-V |
| 280 | * available, but it works for both xapic and x2apic modes. | 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 | apic_set_eoi_write(hv_apic_eoi_write); | 286 | apic_set_eoi_write(hv_apic_eoi_write); |
| 283 | if (!x2apic_enabled()) { | 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 | /* Relies on 'to' being NULL chars so result will be NULL terminated */ | 291 | /* Relies on 'to' being NULL chars so result will be NULL terminated */ |
| 292 | strncpy(to, from, len-1); | 292 | strncpy(to, from, len-1); |
| 293 | |||
| 294 | /* Trim trailing spaces */ | ||
| 295 | (void)strim(to); | ||
| 293 | } | 296 | } |
| 294 | 297 | ||
| 295 | /* Find UV arch type entry in UVsystab */ | 298 | /* Find UV arch type entry in UVsystab */ |
| @@ -366,7 +369,7 @@ static int __init early_get_arch_type(void) · 70 unmodified lines | |||
| 366 | return ret; | 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 | /* Save OEM_ID passed from ACPI MADT */ | 374 | /* Save OEM_ID passed from ACPI MADT */ |
| 372 | uv_stringify(sizeof(oem_id), oem_id, _oem_id); | 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 | /* (Not hubless), not a UV */ | 389 | /* (Not hubless), not a UV */ |
| 387 | return 0; | 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 | /* UV4 Hubless: CH */ | 399 | /* UV4 Hubless: CH */ |
| 390 | if (strncmp(uv_archtype, "NSGI4", 5) == 0) | 400 | else if (strncmp(uv_archtype, "NSGI4", 5) == 0) |
| 391 | uv_hubless_system = 0x11; | 401 | uv_hubless_system |= 0x10; |
| 392 | 402 | ||
| 393 | /* UV3 Hubless: UV300/MC990X w/o hub */ | 403 | /* UV3 Hubless: UV300/MC990X w/o hub */ |
| 394 | else | 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 | pr_info("UV: OEM IDs %s/%s, SystemType %d, HUBLESS ID %x\n", | 410 | pr_info("UV: OEM IDs %s/%s, SystemType %d, HUBLESS ID %x\n", |
| 398 | oem_id, oem_table_id, uv_system_type, uv_hubless_system); | 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 | uv_cpu_info->p_uv_hub_info = &uv_hub_info_node0; | 469 | uv_cpu_info->p_uv_hub_info = &uv_hub_info_node0; |
| 457 | 470 | ||
| 458 | /* If not UV, return. */ | 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 | return 0; | 473 | return 0; |
| 461 | 474 | ||
| 462 | /* Save and Decode OEM Table ID */ | 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 | return 0; | 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 | static int ib_prctl_set(struct task_struct *task, unsigned long ctrl) | 1265 | static int ib_prctl_set(struct task_struct *task, unsigned long ctrl) |
| 1258 | { | 1266 | { |
| 1259 | switch (ctrl) { | 1267 | switch (ctrl) { |
| @@ -1261,16 +1269,26 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl) · 1 unmodified line | |||
| 1261 | if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && | 1269 | if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && |
| 1262 | spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) | 1270 | spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) |
| 1263 | return 0; | 1271 | return 0; |
| 1272 | |||
| 1264 | /* | 1273 | /* |
| 1265 | * Indirect branch speculation is always disabled in strict | 1274 | * With strict mode for both IBPB and STIBP, the instruction |
| 1266 | * mode. It can neither be enabled if it was force-disabled | 1275 | * code paths avoid checking this task flag and instead, |
| 1267 | * by a previous prctl call. | 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 || | 1288 | if (!is_spec_ib_user_controlled() || |
| 1270 | spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT || | ||
| 1271 | spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED || | ||
| 1272 | task_spec_ib_force_disable(task)) | 1289 | task_spec_ib_force_disable(task)) |
| 1273 | return -EPERM; | 1290 | return -EPERM; |
| 1291 | |||
| 1274 | task_clear_spec_ib_disable(task); | 1292 | task_clear_spec_ib_disable(task); |
| 1275 | task_update_spec_tif(task); | 1293 | task_update_spec_tif(task); |
| 1276 | break; | 1294 | break; |
| @@ -1283,10 +1301,10 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl) · 6 unmodified lines | |||
| 1283 | if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && | 1301 | if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && |
| 1284 | spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) | 1302 | spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) |
| 1285 | return -EPERM; | 1303 | return -EPERM; |
| 1286 | if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT || | 1304 | |
| 1287 | spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT || | 1305 | if (!is_spec_ib_user_controlled()) |
| 1288 | spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED) | ||
| 1289 | return 0; | 1306 | return 0; |
| 1307 | |||
| 1290 | task_set_spec_ib_disable(task); | 1308 | task_set_spec_ib_disable(task); |
| 1291 | if (ctrl == PR_SPEC_FORCE_DISABLE) | 1309 | if (ctrl == PR_SPEC_FORCE_DISABLE) |
| 1292 | task_set_spec_ib_force_disable(task); | 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 | if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && | 1369 | if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && |
| 1352 | spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) | 1370 | spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) |
| 1353 | return PR_SPEC_ENABLE; | 1371 | return PR_SPEC_ENABLE; |
| 1354 | else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT || | 1372 | else if (is_spec_ib_user_controlled()) { |
| 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) { | ||
| 1362 | if (task_spec_ib_force_disable(task)) | 1373 | if (task_spec_ib_force_disable(task)) |
| 1363 | return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE; | 1374 | return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE; |
| 1364 | if (task_spec_ib_disable(task)) | 1375 | if (task_spec_ib_disable(task)) |
| 1365 | return PR_SPEC_PRCTL | PR_SPEC_DISABLE; | 1376 | return PR_SPEC_PRCTL | PR_SPEC_DISABLE; |
| 1366 | return PR_SPEC_PRCTL | PR_SPEC_ENABLE; | 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 | return PR_SPEC_NOT_AFFECTED; | 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 | /* Setup early boot stage 4-/5-level pagetables. */ | 162 | /* Setup early boot stage 4-/5-level pagetables. */ |
| 163 | addq phys_base(%rip), %rax | 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 | movq %rax, %cr3 | 179 | movq %rax, %cr3 |
| 165 | 180 | ||
| 166 | /* Ensure I am executing from virtual addresses */ | 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 | SYM_CODE_END(secondary_startup_64) | 294 | SYM_CODE_END(secondary_startup_64) |
| 280 | 295 | ||
| 281 | #include "verify_cpu.S" | 296 | #include "verify_cpu.S" |
| 297 | #include "sev_verify_cbit.S" | ||
| 282 | 298 | ||
| 283 | #ifdef CONFIG_HOTPLUG_CPU | 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 | goto fail; | 178 | goto fail; |
| 179 | regs->dx = val >> 32; | 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 | /* Skip over the CPUID two-byte opcode */ | 207 | /* Skip over the CPUID two-byte opcode */ |
| 182 | regs->ip += 2; | 208 | regs->ip += 2; |
| 183 | 209 | ||
| @@ -374,8 +374,8 @@ fault: · 373 unmodified lines | |||
| 374 | return ES_EXCEPTION; | 374 | return ES_EXCEPTION; |
| 375 | } | 375 | } |
| 376 | 376 | ||
| 377 | static bool vc_slow_virt_to_phys(struct ghcb *ghcb, struct es_em_ctxt *ctxt, | 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) | 378 | unsigned long vaddr, phys_addr_t *paddr) |
| 379 | { | 379 | { |
| 380 | unsigned long va = (unsigned long)vaddr; | 380 | unsigned long va = (unsigned long)vaddr; |
| 381 | unsigned int level; | 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 | if (user_mode(ctxt->regs)) | 394 | if (user_mode(ctxt->regs)) |
| 395 | ctxt->fi.error_code |= X86_PF_USER; | 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 | pa = (phys_addr_t)pte_pfn(*pte) << PAGE_SHIFT; | 404 | pa = (phys_addr_t)pte_pfn(*pte) << PAGE_SHIFT; |
| 401 | pa |= va & ~page_level_mask(level); | 405 | pa |= va & ~page_level_mask(level); |
| 402 | 406 | ||
| 403 | *paddr = pa; | 407 | *paddr = pa; |
| 404 | 408 | ||
| 405 | return true; | 409 | return ES_OK; |
| 406 | } | 410 | } |
| 407 | 411 | ||
| 408 | /* Include code shared with pre-decompression boot stage */ | 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 | u64 exit_code, exit_info_1, exit_info_2; | 736 | u64 exit_code, exit_info_1, exit_info_2; |
| 733 | unsigned long ghcb_pa = __pa(ghcb); | 737 | unsigned long ghcb_pa = __pa(ghcb); |
| 738 | enum es_result res; | ||
| 734 | phys_addr_t paddr; | 739 | phys_addr_t paddr; |
| 735 | void __user *ref; | 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 | exit_code = read ? SVM_VMGEXIT_MMIO_READ : SVM_VMGEXIT_MMIO_WRITE; | 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)) { | 748 | res = vc_slow_virt_to_phys(ghcb, ctxt, (unsigned long)ref, &paddr); |
| 744 | if (!read) | 749 | if (res != ES_OK) { |
| 750 | if (res == ES_EXCEPTION && !read) | ||
| 745 | ctxt->fi.error_code |= X86_PF_WRITE; | 751 | ctxt->fi.error_code |= X86_PF_WRITE; |
| 746 | 752 | ||
| 747 | return ES_EXCEPTION; | 753 | return res; |
| 748 | } | 754 | } |
| 749 | 755 | ||
| 750 | exit_info_1 = paddr; | 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 | * to a jmp to memcpy_erms which does the REP; MOVSB mem copy. | 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 | * memcpy - Copy a memory block. | 20 | * memcpy - Copy a memory block. |
| 23 | * | 21 | * |
| @@ -30,7 +28,7 @@ · 6 unmodified lines | |||
| 30 | * rax original destination | 28 | * rax original destination |
| 31 | */ | 29 | */ |
| 32 | SYM_FUNC_START_ALIAS(__memcpy) | 30 | SYM_FUNC_START_ALIAS(__memcpy) |
| 33 | SYM_FUNC_START_LOCAL(memcpy) | 31 | SYM_FUNC_START_WEAK(memcpy) |
| 34 | ALTERNATIVE_2 "jmp memcpy_orig", "", X86_FEATURE_REP_GOOD, \ | 32 | ALTERNATIVE_2 "jmp memcpy_orig", "", X86_FEATURE_REP_GOOD, \ |
| 35 | "jmp memcpy_erms", X86_FEATURE_ERMS | 33 | "jmp memcpy_erms", X86_FEATURE_ERMS |
| 36 | 34 | ||
| @@ -24,9 +24,7 @@ · 23 unmodified lines | |||
| 24 | * Output: | 24 | * Output: |
| 25 | * rax: dest | 25 | * rax: dest |
| 26 | */ | 26 | */ |
| 27 | .weak memmove | 27 | SYM_FUNC_START_WEAK(memmove) |
| 28 | |||
| 29 | SYM_FUNC_START_ALIAS(memmove) | ||
| 30 | SYM_FUNC_START(__memmove) | 28 | SYM_FUNC_START(__memmove) |
| 31 | 29 | ||
| 32 | mov %rdi, %rax | 30 | mov %rdi, %rax |
| @@ -6,8 +6,6 @@ · 5 unmodified lines | |||
| 6 | #include <asm/alternative-asm.h> | 6 | #include <asm/alternative-asm.h> |
| 7 | #include <asm/export.h> | 7 | #include <asm/export.h> |
| 8 | 8 | ||
| 9 | .weak memset | ||
| 10 | |||
| 11 | /* | 9 | /* |
| 12 | * ISO C memset - set a memory block to a byte value. This function uses fast | 10 | * ISO C memset - set a memory block to a byte value. This function uses fast |
| 13 | * string to get better performance than the original function. The code is | 11 | * string to get better performance than the original function. The code is |
| @@ -19,7 +17,7 @@ · 5 unmodified lines | |||
| 19 | * | 17 | * |
| 20 | * rax original destination | 18 | * rax original destination |
| 21 | */ | 19 | */ |
| 22 | SYM_FUNC_START_ALIAS(memset) | 20 | SYM_FUNC_START_WEAK(memset) |
| 23 | SYM_FUNC_START(__memset) | 21 | SYM_FUNC_START(__memset) |
| 24 | /* | 22 | /* |
| 25 | * Some CPUs support enhanced REP MOVSB/STOSB feature. It is recommended | 23 | * Some CPUs support enhanced REP MOVSB/STOSB feature. It is recommended |
| @@ -39,6 +39,7 @@ · 38 unmodified lines | |||
| 39 | */ | 39 | */ |
| 40 | u64 sme_me_mask __section(".data") = 0; | 40 | u64 sme_me_mask __section(".data") = 0; |
| 41 | u64 sev_status __section(".data") = 0; | 41 | u64 sev_status __section(".data") = 0; |
| 42 | u64 sev_check_data __section(".data") = 0; | ||
| 42 | EXPORT_SYMBOL(sme_me_mask); | 43 | EXPORT_SYMBOL(sme_me_mask); |
| 43 | DEFINE_STATIC_KEY_FALSE(sev_enable_key); | 44 | DEFINE_STATIC_KEY_FALSE(sev_enable_key); |
| 44 | EXPORT_SYMBOL_GPL(sev_enable_key); | 45 | EXPORT_SYMBOL_GPL(sev_enable_key); |
| @@ -89,8 +89,8 @@ static void __init free_highpages(void) · 88 unmodified lines | |||
| 89 | /* set highmem page free */ | 89 | /* set highmem page free */ |
| 90 | for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, | 90 | for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, |
| 91 | &range_start, &range_end, NULL) { | 91 | &range_start, &range_end, NULL) { |
| 92 | unsigned long start = PHYS_PFN(range_start); | 92 | unsigned long start = PFN_UP(range_start); |
| 93 | unsigned long end = PHYS_PFN(range_end); | 93 | unsigned long end = PFN_DOWN(range_end); |
| 94 | 94 | ||
| 95 | /* Ignore complete lowmem entries */ | 95 | /* Ignore complete lowmem entries */ |
| 96 | if (end <= max_low) | 96 | if (end <= max_low) |
| @@ -773,8 +773,7 @@ static void __device_link_del(struct kref *kref) · 772 unmodified lines | |||
| 773 | dev_dbg(link->consumer, "Dropping the link to %s\n", | 773 | dev_dbg(link->consumer, "Dropping the link to %s\n", |
| 774 | dev_name(link->supplier)); | 774 | dev_name(link->supplier)); |
| 775 | 775 | ||
| 776 | if (link->flags & DL_FLAG_PM_RUNTIME) | 776 | pm_runtime_drop_link(link); |
| 777 | pm_runtime_drop_link(link->consumer); | ||
| 778 | 777 | ||
| 779 | list_del_rcu(&link->s_node); | 778 | list_del_rcu(&link->s_node); |
| 780 | list_del_rcu(&link->c_node); | 779 | list_del_rcu(&link->c_node); |
| @@ -788,8 +787,7 @@ static void __device_link_del(struct kref *kref) · 7 unmodified lines | |||
| 788 | dev_info(link->consumer, "Dropping the link to %s\n", | 787 | dev_info(link->consumer, "Dropping the link to %s\n", |
| 789 | dev_name(link->supplier)); | 788 | dev_name(link->supplier)); |
| 790 | 789 | ||
| 791 | if (link->flags & DL_FLAG_PM_RUNTIME) | 790 | pm_runtime_drop_link(link); |
| 792 | pm_runtime_drop_link(link->consumer); | ||
| 793 | 791 | ||
| 794 | list_del(&link->s_node); | 792 | list_del(&link->s_node); |
| 795 | list_del(&link->c_node); | 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 | drv = dev->driver; | 1118 | drv = dev->driver; |
| 1119 | if (drv) { | 1119 | if (drv) { |
| 1120 | pm_runtime_get_sync(dev); | ||
| 1121 | |||
| 1120 | while (device_links_busy(dev)) { | 1122 | while (device_links_busy(dev)) { |
| 1121 | __device_driver_unlock(dev, parent); | 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 | * have released the driver successfully while this one | 1130 | * have released the driver successfully while this one |
| 1129 | * was waiting, so check for that. | 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 | return; | 1135 | return; |
| 1136 | } | ||
| 1133 | } | 1137 | } |
| 1134 | 1138 | ||
| 1135 | pm_runtime_get_sync(dev); | ||
| 1136 | pm_runtime_clean_up_links(dev); | ||
| 1137 | |||
| 1138 | driver_sysfs_remove(dev); | 1139 | driver_sysfs_remove(dev); |
| 1139 | 1140 | ||
| 1140 | if (dev->bus) | 1141 | if (dev->bus) |
| @@ -1642,42 +1642,6 @@ void pm_runtime_remove(struct device *dev) · 1641 unmodified lines | |||
| 1642 | pm_runtime_reinit(dev); | 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 | * pm_runtime_get_suppliers - Resume and reference-count supplier devices. | 1646 | * pm_runtime_get_suppliers - Resume and reference-count supplier devices. |
| 1683 | * @dev: Consumer device. | 1647 | * @dev: Consumer device. |
| @@ -1729,7 +1693,7 @@ void pm_runtime_new_link(struct device *dev) · 45 unmodified lines | |||
| 1729 | spin_unlock_irq(&dev->power.lock); | 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 | spin_lock_irq(&dev->power.lock); | 1698 | spin_lock_irq(&dev->power.lock); |
| 1735 | WARN_ON(dev->power.links_count == 0); | 1699 | WARN_ON(dev->power.links_count == 0); |
| @@ -1737,6 +1701,25 @@ void pm_runtime_drop_link(struct device *dev) · 1 unmodified line | |||
| 1737 | spin_unlock_irq(&dev->power.lock); | 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 | static bool pm_runtime_need_not_resume(struct device *dev) | 1723 | static bool pm_runtime_need_not_resume(struct device *dev) |
| 1741 | { | 1724 | { |
| 1742 | return atomic_read(&dev->power.usage_count) <= 1 && | 1725 | return atomic_read(&dev->power.usage_count) <= 1 && |
| @@ -47,7 +47,7 @@ struct nullb_device { · 46 unmodified lines | |||
| 47 | unsigned int nr_zones_closed; | 47 | unsigned int nr_zones_closed; |
| 48 | struct blk_zone *zones; | 48 | struct blk_zone *zones; |
| 49 | sector_t zone_size_sects; | 49 | sector_t zone_size_sects; |
| 50 | spinlock_t zone_dev_lock; | 50 | spinlock_t zone_lock; |
| 51 | unsigned long *zone_locks; | 51 | unsigned long *zone_locks; |
| 52 | 52 | ||
| 53 | unsigned long size; /* device size in MB */ | 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 | if (!dev->zones) | 46 | if (!dev->zones) |
| 47 | return -ENOMEM; | 47 | return -ENOMEM; |
| 48 | 48 | ||
| 49 | spin_lock_init(&dev->zone_dev_lock); | 49 | /* |
| 50 | dev->zone_locks = bitmap_zalloc(dev->nr_zones, GFP_KERNEL); | 50 | * With memory backing, the zone_lock spinlock needs to be temporarily |
| 51 | if (!dev->zone_locks) { | 51 | * released to avoid scheduling in atomic context. To guarantee zone |
| 52 | kvfree(dev->zones); | 52 | * information protection, use a bitmap to lock zones with |
| 53 | return -ENOMEM; | 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 | if (dev->zone_nr_conv >= dev->nr_zones) { | 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 | static inline void null_lock_zone(struct nullb_device *dev, unsigned int zno) | 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 | static inline void null_unlock_zone(struct nullb_device *dev, unsigned int zno) | 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 | int null_report_zones(struct gendisk *disk, sector_t sector, | 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 | return null_process_cmd(cmd, REQ_OP_WRITE, sector, nr_sectors); | 336 | return null_process_cmd(cmd, REQ_OP_WRITE, sector, nr_sectors); |
| 323 | 337 | ||
| 324 | null_lock_zone(dev, zno); | 338 | null_lock_zone(dev, zno); |
| 325 | spin_lock(&dev->zone_dev_lock); | ||
| 326 | 339 | ||
| 327 | switch (zone->cond) { | 340 | switch (zone->cond) { |
| 328 | case BLK_ZONE_COND_FULL: | 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 | if (zone->cond != BLK_ZONE_COND_EXP_OPEN) | 388 | if (zone->cond != BLK_ZONE_COND_EXP_OPEN) |
| 376 | zone->cond = BLK_ZONE_COND_IMP_OPEN; | 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 | ret = null_process_cmd(cmd, REQ_OP_WRITE, sector, nr_sectors); | 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 | if (ret != BLK_STS_OK) | 402 | if (ret != BLK_STS_OK) |
| 382 | goto unlock; | 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 | ret = BLK_STS_OK; | 413 | ret = BLK_STS_OK; |
| 393 | 414 | ||
| 394 | unlock: | 415 | unlock: |
| 395 | spin_unlock(&dev->zone_dev_lock); | ||
| 396 | null_unlock_zone(dev, zno); | 416 | null_unlock_zone(dev, zno); |
| 397 | 417 | ||
| 398 | return ret; | 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 | null_lock_zone(dev, i); | 536 | null_lock_zone(dev, i); |
| 517 | zone = &dev->zones[i]; | 537 | zone = &dev->zones[i]; |
| 518 | if (zone->cond != BLK_ZONE_COND_EMPTY) { | 538 | if (zone->cond != BLK_ZONE_COND_EMPTY) { |
| 519 | spin_lock(&dev->zone_dev_lock); | ||
| 520 | null_reset_zone(dev, zone); | 539 | null_reset_zone(dev, zone); |
| 521 | spin_unlock(&dev->zone_dev_lock); | ||
| 522 | trace_nullb_zone_op(cmd, i, zone->cond); | 540 | trace_nullb_zone_op(cmd, i, zone->cond); |
| 523 | } | 541 | } |
| 524 | null_unlock_zone(dev, i); | 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 | zone = &dev->zones[zone_no]; | 548 | zone = &dev->zones[zone_no]; |
| 531 | 549 | ||
| 532 | null_lock_zone(dev, zone_no); | 550 | null_lock_zone(dev, zone_no); |
| 533 | spin_lock(&dev->zone_dev_lock); | ||
| 534 | 551 | ||
| 535 | switch (op) { | 552 | switch (op) { |
| 536 | case REQ_OP_ZONE_RESET: | 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 | break; | 567 | break; |
| 551 | } | 568 | } |
| 552 | 569 | ||
| 553 | spin_unlock(&dev->zone_dev_lock); | ||
| 554 | |||
| 555 | if (ret == BLK_STS_OK) | 570 | if (ret == BLK_STS_OK) |
| 556 | trace_nullb_zone_op(cmd, zone_no, zone->cond); | 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 | log_size = log_tbl->size; | 41 | log_size = log_tbl->size; |
| 42 | memunmap(log_tbl); | 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 | log_tbl = memremap(efi.tpm_log, sizeof(*log_tbl) + log_size, | 49 | log_tbl = memremap(efi.tpm_log, sizeof(*log_tbl) + log_size, |
| 45 | MEMREMAP_WB); | 50 | MEMREMAP_WB); |
| 46 | if (!log_tbl) { | 51 | if (!log_tbl) { |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | |||
| 27 | #include <linux/of.h> | 27 | #include <linux/of.h> |
| 28 | #include <linux/of_device.h> | 28 | #include <linux/of_device.h> |
| 29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
| 30 | #include <linux/dmi.h> | ||
| 30 | #include "tpm.h" | 31 | #include "tpm.h" |
| 31 | #include "tpm_tis_core.h" | 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 | return container_of(data, struct tpm_tis_tcg_phy, priv); | 50 | return container_of(data, struct tpm_tis_tcg_phy, priv); |
| 50 | } | 51 | } |
| 51 | 52 | ||
| 52 | static bool interrupts = true; | 53 | static int interrupts = -1; |
| 53 | module_param(interrupts, bool, 0444); | 54 | module_param(interrupts, int, 0444); |
| 54 | MODULE_PARM_DESC(interrupts, "Enable interrupts"); | 55 | MODULE_PARM_DESC(interrupts, "Enable interrupts"); |
| 55 | 56 | ||
| 56 | static bool itpm; | 57 | static bool itpm; |
| @@ -63,6 +64,28 @@ module_param(force, bool, 0444); · 6 unmodified lines | |||
| 63 | MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry"); | 64 | MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry"); |
| 64 | #endif | 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 | #if defined(CONFIG_PNP) && defined(CONFIG_ACPI) | 89 | #if defined(CONFIG_PNP) && defined(CONFIG_ACPI) |
| 67 | static int has_hid(struct acpi_device *dev, const char *hid) | 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 | int irq = -1; | 215 | int irq = -1; |
| 193 | int rc; | 216 | int rc; |
| 194 | 217 | ||
| 218 | dmi_check_system(tpm_tis_dmi_table); | ||
| 219 | |||
| 195 | rc = check_acpi_tpm2(dev); | 220 | rc = check_acpi_tpm2(dev); |
| 196 | if (rc) | 221 | if (rc) |
| 197 | return rc; | 222 | return rc; |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | |||
| 7 | * | 7 | * |
| 8 | * This file add support for MD5 and SHA1/SHA224/SHA256/SHA384/SHA512. | 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 | #include <linux/dma-mapping.h> | 12 | #include <linux/dma-mapping.h> |
| 13 | #include <linux/pm_runtime.h> | 13 | #include <linux/pm_runtime.h> |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | |||
| 7 | * | 7 | * |
| 8 | * This file handle the PRNG | 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 | #include "sun8i-ce.h" | 12 | #include "sun8i-ce.h" |
| 13 | #include <linux/dma-mapping.h> | 13 | #include <linux/dma-mapping.h> |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | |||
| 7 | * | 7 | * |
| 8 | * This file handle the TRNG | 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 | #include "sun8i-ce.h" | 12 | #include "sun8i-ce.h" |
| 13 | #include <linux/dma-mapping.h> | 13 | #include <linux/dma-mapping.h> |
| @@ -55,7 +55,8 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \ · 54 unmodified lines | |||
| 55 | amdgpu_vf_error.o amdgpu_sched.o amdgpu_debugfs.o amdgpu_ids.o \ | 55 | amdgpu_vf_error.o amdgpu_sched.o amdgpu_debugfs.o amdgpu_ids.o \ |
| 56 | amdgpu_gmc.o amdgpu_mmhub.o amdgpu_xgmi.o amdgpu_csa.o amdgpu_ras.o amdgpu_vm_cpu.o \ | 56 | amdgpu_gmc.o amdgpu_mmhub.o amdgpu_xgmi.o amdgpu_csa.o amdgpu_ras.o amdgpu_vm_cpu.o \ |
| 57 | amdgpu_vm_sdma.o amdgpu_discovery.o amdgpu_ras_eeprom.o amdgpu_nbio.o \ | 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 | amdgpu-$(CONFIG_PERF_EVENTS) += amdgpu_pmu.o | 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 | amdgpu-y += \ | 70 | amdgpu-y += \ |
| 70 | 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 | 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 | vega20_reg_init.o nbio_v7_4.o nbio_v2_3.o nv.o navi10_reg_init.o navi14_reg_init.o \ | 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 | # add DF block | 76 | # add DF block |
| 75 | amdgpu-y += \ | 77 | amdgpu-y += \ |
| @@ -81,7 +83,7 @@ amdgpu-y += \ · 5 unmodified lines | |||
| 81 | gmc_v7_0.o \ | 83 | gmc_v7_0.o \ |
| 82 | gmc_v8_0.o \ | 84 | gmc_v8_0.o \ |
| 83 | gfxhub_v1_0.o mmhub_v1_0.o gmc_v9_0.o gfxhub_v1_1.o mmhub_v9_4.o \ | 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 | # add UMC block | 88 | # add UMC block |
| 87 | amdgpu-y += \ | 89 | amdgpu-y += \ |
| @@ -623,6 +623,8 @@ struct amdgpu_asic_funcs { · 622 unmodified lines | |||
| 623 | bool (*supports_baco)(struct amdgpu_device *adev); | 623 | bool (*supports_baco)(struct amdgpu_device *adev); |
| 624 | /* pre asic_init quirks */ | 624 | /* pre asic_init quirks */ |
| 625 | void (*pre_asic_init)(struct amdgpu_device *adev); | 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 | const struct amd_pm_funcs *pp_funcs; | 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 | #define AMDGPU_RESET_MAGIC_NUM 64 | 767 | #define AMDGPU_RESET_MAGIC_NUM 64 |
| 727 | #define AMDGPU_MAX_DF_PERFMONS 4 | 768 | #define AMDGPU_MAX_DF_PERFMONS 4 |
| 728 | struct amdgpu_device { | 769 | struct amdgpu_device { |
| @@ -1165,6 +1206,8 @@ int emu_soc_asic_init(struct amdgpu_device *adev); · 436 unmodified lines | |||
| 1165 | #define amdgpu_asic_get_pcie_replay_count(adev) ((adev)->asic_funcs->get_pcie_replay_count((adev))) | 1206 | #define amdgpu_asic_get_pcie_replay_count(adev) ((adev)->asic_funcs->get_pcie_replay_count((adev))) |
| 1166 | #define amdgpu_asic_supports_baco(adev) (adev)->asic_funcs->supports_baco((adev)) | 1207 | #define amdgpu_asic_supports_baco(adev) (adev)->asic_funcs->supports_baco((adev)) |
| 1167 | #define amdgpu_asic_pre_asic_init(adev) (adev)->asic_funcs->pre_asic_init((adev)) | 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 | #define amdgpu_inc_vram_lost(adev) atomic_inc(&((adev)->vram_lost_counter)); | 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 | #include "amdgpu_object.h" | 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 | static inline bool amdgpu_is_tmz(struct amdgpu_device *adev) | 1340 | static inline bool amdgpu_is_tmz(struct amdgpu_device *adev) |
| 1311 | { | 1341 | { |
| 1312 | return adev->gmc.tmz_enabled; | 1342 | return adev->gmc.tmz_enabled; |
| @@ -36,17 +36,17 @@ · 35 unmodified lines | |||
| 36 | 36 | ||
| 37 | #include "acp_gfx_if.h" | 37 | #include "acp_gfx_if.h" |
| 38 | 38 | ||
| 39 | #define ACP_TILE_ON_MASK 0x03 | 39 | #define ACP_TILE_ON_MASK 0x03 |
| 40 | #define ACP_TILE_OFF_MASK 0x02 | 40 | #define ACP_TILE_OFF_MASK 0x02 |
| 41 | #define ACP_TILE_ON_RETAIN_REG_MASK 0x1f | 41 | #define ACP_TILE_ON_RETAIN_REG_MASK 0x1f |
| 42 | #define ACP_TILE_OFF_RETAIN_REG_MASK 0x20 | 42 | #define ACP_TILE_OFF_RETAIN_REG_MASK 0x20 |
| 43 | 43 | ||
| 44 | #define ACP_TILE_P1_MASK 0x3e | 44 | #define ACP_TILE_P1_MASK 0x3e |
| 45 | #define ACP_TILE_P2_MASK 0x3d | 45 | #define ACP_TILE_P2_MASK 0x3d |
| 46 | #define ACP_TILE_DSP0_MASK 0x3b | 46 | #define ACP_TILE_DSP0_MASK 0x3b |
| 47 | #define ACP_TILE_DSP1_MASK 0x37 | 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 | #define ACP_DMA_REGS_END 0x146c0 | 51 | #define ACP_DMA_REGS_END 0x146c0 |
| 52 | #define ACP_I2S_PLAY_REGS_START 0x14840 | 52 | #define ACP_I2S_PLAY_REGS_START 0x14840 |
| @@ -75,8 +75,8 @@ · 22 unmodified lines | |||
| 75 | #define mmACP_CONTROL 0x5131 | 75 | #define mmACP_CONTROL 0x5131 |
| 76 | #define mmACP_STATUS 0x5133 | 76 | #define mmACP_STATUS 0x5133 |
| 77 | #define mmACP_SOFT_RESET 0x5134 | 77 | #define mmACP_SOFT_RESET 0x5134 |
| 78 | #define ACP_CONTROL__ClkEn_MASK 0x1 | 78 | #define ACP_CONTROL__ClkEn_MASK 0x1 |
| 79 | #define ACP_SOFT_RESET__SoftResetAud_MASK 0x100 | 79 | #define ACP_SOFT_RESET__SoftResetAud_MASK 0x100 |
| 80 | #define ACP_SOFT_RESET__SoftResetAudDone_MASK 0x1000000 | 80 | #define ACP_SOFT_RESET__SoftResetAudDone_MASK 0x1000000 |
| 81 | #define ACP_CLOCK_EN_TIME_OUT_VALUE 0x000000FF | 81 | #define ACP_CLOCK_EN_TIME_OUT_VALUE 0x000000FF |
| 82 | #define ACP_SOFT_RESET_DONE_TIME_OUT_VALUE 0x000000FF | 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 | struct kfd_local_mem_info *mem_info) | 390 | struct kfd_local_mem_info *mem_info) |
| 391 | { | 391 | { |
| 392 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; | 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 | memset(mem_info, 0, sizeof(*mem_info)); | 394 | memset(mem_info, 0, sizeof(*mem_info)); |
| 398 | if (!(adev->gmc.aper_base & address_mask || aper_limit & address_mask)) { | 395 | |
| 399 | mem_info->local_mem_size_public = adev->gmc.visible_vram_size; | 396 | mem_info->local_mem_size_public = adev->gmc.visible_vram_size; |
| 400 | mem_info->local_mem_size_private = adev->gmc.real_vram_size - | 397 | mem_info->local_mem_size_private = adev->gmc.real_vram_size - |
| 401 | adev->gmc.visible_vram_size; | 398 | adev->gmc.visible_vram_size; |
| 402 | } else { | 399 | |
| 403 | mem_info->local_mem_size_public = 0; | ||
| 404 | mem_info->local_mem_size_private = adev->gmc.real_vram_size; | ||
| 405 | } | ||
| 406 | mem_info->vram_width = adev->gmc.vram_width; | 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", | 402 | pr_debug("Address base: %pap public 0x%llx private 0x%llx\n", |
| 409 | &adev->gmc.aper_base, &aper_limit, | 403 | &adev->gmc.aper_base, |
| 410 | mem_info->local_mem_size_public, | 404 | mem_info->local_mem_size_public, |
| 411 | mem_info->local_mem_size_private); | 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 | struct amdgpu_device *adev = (struct amdgpu_device *)kgd; | 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 | amdgpu_dpm_switch_power_profile(adev, | 652 | amdgpu_dpm_switch_power_profile(adev, |
| 652 | PP_SMC_POWER_PROFILE_COMPUTE, | 653 | PP_SMC_POWER_PROFILE_COMPUTE, |
| 653 | !idle); | 654 | !idle); |
| @@ -304,4 +304,5 @@ const struct kfd2kgd_calls arcturus_kfd2kgd = { · 303 unmodified lines | |||
| 304 | kgd_gfx_v9_get_atc_vmid_pasid_mapping_info, | 304 | kgd_gfx_v9_get_atc_vmid_pasid_mapping_info, |
| 305 | .set_vm_context_page_table_base = | 305 | .set_vm_context_page_table_base = |
| 306 | kgd_gfx_v9_set_vm_context_page_table_base, | 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 | * Reading registers referenced above involves programming GRBM appropriately | 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 | int *pasid_wave_cnt, int *max_waves_per_cu) | 803 | int *pasid_wave_cnt, int *max_waves_per_cu) |
| 804 | { | 804 | { |
| 805 | int qidx; | 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 | void kgd_gfx_v9_set_vm_context_page_table_base(struct kgd_dev *kgd, | 64 | void kgd_gfx_v9_set_vm_context_page_table_base(struct kgd_dev *kgd, |
| 65 | uint32_t vmid, uint64_t page_table_base); | 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 | if (!old) | 239 | if (!old) |
| 240 | return 0; | 240 | return 0; |
| 241 | 241 | ||
| 242 | new = kmalloc(offsetof(typeof(*new), shared[old->shared_max]), | 242 | new = kmalloc(struct_size(new, shared, old->shared_max), GFP_KERNEL); |
| 243 | GFP_KERNEL); | ||
| 244 | if (!new) | 243 | if (!new) |
| 245 | return -ENOMEM; | 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 | void amdgpu_amdkfd_gpuvm_release_process_vm(struct kgd_dev *kgd, void *vm) | 1114 | void amdgpu_amdkfd_gpuvm_release_process_vm(struct kgd_dev *kgd, void *vm) |
| 1116 | { | 1115 | { |
| 1117 | struct amdgpu_device *adev = get_amdgpu_device(kgd); | 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 | if (WARN_ON(!kgd || !vm)) | 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 | 1124 | /* The original pasid of amdgpu vm has already been |
| 1126 | * released during making a amdgpu vm to a compute vm | 1125 | * released during making a amdgpu vm to a compute vm |
| 1127 | * The current pasid is managed by kfd and will be | 1126 | * The current pasid is managed by kfd and will be |
| 1128 | * released on kfd process destroy. Set amdgpu pasid | 1127 | * released on kfd process destroy. Set amdgpu pasid |
| 1129 | * to 0 to avoid duplicate release. | 1128 | * to 0 to avoid duplicate release. |
| 1130 | */ | 1129 | */ |
| 1131 | amdgpu_vm_release_compute(adev, avm); | 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 | struct ttm_validate_buffer *bo_list_entry; | 1287 | struct ttm_validate_buffer *bo_list_entry; |
| 1289 | unsigned int mapped_to_gpu_memory; | 1288 | unsigned int mapped_to_gpu_memory; |
| 1290 | int ret; | 1289 | int ret; |
| 1291 | bool is_imported = 0; | 1290 | bool is_imported = false; |
| 1292 | 1291 | ||
| 1293 | mutex_lock(&mem->lock); | 1292 | mutex_lock(&mem->lock); |
| 1294 | mapped_to_gpu_memory = mem->mapped_to_gpu_memory; | 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 | INIT_LIST_HEAD(&(*mem)->bo_va_list); | 1695 | INIT_LIST_HEAD(&(*mem)->bo_va_list); |
| 1697 | mutex_init(&(*mem)->lock); | 1696 | mutex_init(&(*mem)->lock); |
| 1698 | 1697 | ||
| 1699 | (*mem)->alloc_flags = | 1698 | (*mem)->alloc_flags = |
| 1700 | ((bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) ? | 1699 | ((bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) ? |
| 1701 | KFD_IOC_ALLOC_MEM_FLAGS_VRAM : KFD_IOC_ALLOC_MEM_FLAGS_GTT) | 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 | u32 size = le16_to_cpu(v3->sHeader.usStructureSize); | 1402 | u32 size = le16_to_cpu(v3->sHeader.usStructureSize); |
| 1403 | u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V3_1, asVoltageObj[0]); | 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 | while (offset < size) { | 1406 | while (offset < size) { |
| 1407 | ATOM_VOLTAGE_OBJECT_V3 *vo = (ATOM_VOLTAGE_OBJECT_V3 *)(start + offset); | 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 | struct atom_context *ctx = adev->mode_info.atom_context; | 70 | struct atom_context *ctx = adev->mode_info.atom_context; |
| 71 | int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, | 71 | int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, |
| 72 | vram_usagebyfirmware); | 72 | vram_usagebyfirmware); |
| 73 | struct vram_usagebyfirmware_v2_1 * firmware_usage; | 73 | struct vram_usagebyfirmware_v2_1 *firmware_usage; |
| 74 | uint32_t start_addr, size; | 74 | uint32_t start_addr, size; |
| 75 | uint16_t data_offset; | 75 | uint16_t data_offset; |
| 76 | int usage_bytes = 0; | 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 | case LpDdr4MemType: | 149 | case LpDdr4MemType: |
| 150 | vram_type = AMDGPU_VRAM_TYPE_DDR4; | 150 | vram_type = AMDGPU_VRAM_TYPE_DDR4; |
| 151 | break; | 151 | break; |
| 152 | case Ddr5MemType: | ||
| 153 | case LpDdr5MemType: | ||
| 154 | vram_type = AMDGPU_VRAM_TYPE_DDR5; | ||
| 155 | break; | ||
| 152 | default: | 156 | default: |
| 153 | vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; | 157 | vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; |
| 154 | break; | 158 | break; |
| @@ -544,6 +548,7 @@ int amdgpu_mem_train_support(struct amdgpu_device *adev) · 389 unmodified lines | |||
| 544 | case HW_REV(11, 0, 5): | 548 | case HW_REV(11, 0, 5): |
| 545 | case HW_REV(11, 0, 7): | 549 | case HW_REV(11, 0, 7): |
| 546 | case HW_REV(11, 0, 11): | 550 | case HW_REV(11, 0, 11): |
| 551 | case HW_REV(11, 0, 12): | ||
| 547 | ret = 1; | 552 | ret = 1; |
| 548 | break; | 553 | break; |
| 549 | default: | 554 | default: |
| @@ -352,17 +352,10 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, · 351 unmodified lines | |||
| 352 | break; | 352 | break; |
| 353 | case CHIP_POLARIS11: | 353 | case CHIP_POLARIS11: |
| 354 | if (type == CGS_UCODE_ID_SMU) { | 354 | if (type == CGS_UCODE_ID_SMU) { |
| 355 | if (((adev->pdev->device == 0x67ef) && | 355 | if (ASICID_IS_P21(adev->pdev->device, adev->pdev->revision)) { |
| 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)))) { | ||
| 362 | info->is_kicker = true; | 356 | info->is_kicker = true; |
| 363 | strcpy(fw_name, "amdgpu/polaris11_k_smc.bin"); | 357 | strcpy(fw_name, "amdgpu/polaris11_k_smc.bin"); |
| 364 | } else if ((adev->pdev->device == 0x67ef) && | 358 | } else if (ASICID_IS_P31(adev->pdev->device, adev->pdev->revision)) { |
| 365 | (adev->pdev->revision == 0xe2)) { | ||
| 366 | info->is_kicker = true; | 359 | info->is_kicker = true; |
| 367 | strcpy(fw_name, "amdgpu/polaris11_k2_smc.bin"); | 360 | strcpy(fw_name, "amdgpu/polaris11_k2_smc.bin"); |
| 368 | } else { | 361 | } else { |
| @@ -374,21 +367,10 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, · 5 unmodified lines | |||
| 374 | break; | 367 | break; |
| 375 | case CHIP_POLARIS10: | 368 | case CHIP_POLARIS10: |
| 376 | if (type == CGS_UCODE_ID_SMU) { | 369 | if (type == CGS_UCODE_ID_SMU) { |
| 377 | if (((adev->pdev->device == 0x67df) && | 370 | if (ASICID_IS_P20(adev->pdev->device, adev->pdev->revision)) { |
| 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)))) { | ||
| 387 | info->is_kicker = true; | 371 | info->is_kicker = true; |
| 388 | strcpy(fw_name, "amdgpu/polaris10_k_smc.bin"); | 372 | strcpy(fw_name, "amdgpu/polaris10_k_smc.bin"); |
| 389 | } else if ((adev->pdev->device == 0x67df) && | 373 | } else if (ASICID_IS_P30(adev->pdev->device, adev->pdev->revision)) { |
| 390 | ((adev->pdev->revision == 0xe1) || | ||
| 391 | (adev->pdev->revision == 0xf7))) { | ||
| 392 | info->is_kicker = true; | 374 | info->is_kicker = true; |
| 393 | strcpy(fw_name, "amdgpu/polaris10_k2_smc.bin"); | 375 | strcpy(fw_name, "amdgpu/polaris10_k2_smc.bin"); |
| 394 | } else { | 376 | } else { |
| @@ -399,13 +381,7 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, · 4 unmodified lines | |||
| 399 | } | 381 | } |
| 400 | break; | 382 | break; |
| 401 | case CHIP_POLARIS12: | 383 | case CHIP_POLARIS12: |
| 402 | if (((adev->pdev->device == 0x6987) && | 384 | if (ASICID_IS_P23(adev->pdev->device, adev->pdev->revision)) { |
| 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)))) { | ||
| 409 | info->is_kicker = true; | 385 | info->is_kicker = true; |
| 410 | strcpy(fw_name, "amdgpu/polaris12_k_smc.bin"); | 386 | strcpy(fw_name, "amdgpu/polaris12_k_smc.bin"); |
| 411 | } else { | 387 | } else { |
| @@ -326,7 +326,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev, · 325 unmodified lines | |||
| 326 | increment_us = time_us - adev->mm_stats.last_update_us; | 326 | increment_us = time_us - adev->mm_stats.last_update_us; |
| 327 | adev->mm_stats.last_update_us = time_us; | 327 | adev->mm_stats.last_update_us = time_us; |
| 328 | adev->mm_stats.accum_us = min(adev->mm_stats.accum_us + increment_us, | 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 | /* This prevents the short period of low performance when the VRAM | 331 | /* This prevents the short period of low performance when the VRAM |
| 332 | * usage is low and the driver is in debt or doesn't have enough | 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 | dma_fence_put(fence); | 1460 | dma_fence_put(fence); |
| 1461 | if (r) | 1461 | if (r) |
| 1462 | return r; | 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 | drm_syncobj_put(syncobj); | 1464 | drm_syncobj_put(syncobj); |
| 1465 | return r; | 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 | enum drm_sched_priority priority; | 100 | enum drm_sched_priority priority; |
| 101 | int r; | 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 | GFP_KERNEL); | 104 | GFP_KERNEL); |
| 105 | if (!entity) | 105 | if (!entity) |
| 106 | return -ENOMEM; | 106 | return -ENOMEM; |
| @@ -450,7 +450,7 @@ int amdgpu_ctx_put(struct amdgpu_ctx *ctx) · 343 unmodified lines | |||
| 450 | 450 | ||
| 451 | void amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, | 451 | void amdgpu_ctx_add_fence(struct amdgpu_ctx *ctx, |
| 452 | struct drm_sched_entity *entity, | 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 | struct amdgpu_ctx_entity *centity = to_amdgpu_ctx_entity(entity); | 455 | struct amdgpu_ctx_entity *centity = to_amdgpu_ctx_entity(entity); |
| 456 | uint64_t seq = centity->sequence; | 456 | uint64_t seq = centity->sequence; |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | |||
| 35 | #include "amdgpu_dm_debugfs.h" | 35 | #include "amdgpu_dm_debugfs.h" |
| 36 | #include "amdgpu_ras.h" | 36 | #include "amdgpu_ras.h" |
| 37 | #include "amdgpu_rap.h" | 37 | #include "amdgpu_rap.h" |
| 38 | #include "amdgpu_fw_attestation.h" | ||
| 38 | 39 | ||
| 39 | /** | 40 | /** |
| 40 | * amdgpu_debugfs_add_files - Add simple debugfs entries | 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 | * Bit 62: Indicates a GRBM bank switch is needed | 171 | * Bit 62: Indicates a GRBM bank switch is needed |
| 171 | * Bit 61: Indicates a SRBM bank switch is needed (implies bit 62 is | 172 | * Bit 61: Indicates a SRBM bank switch is needed (implies bit 62 is |
| 172 | * zero) | 173 | * zero) |
| 173 | * Bits 24..33: The SE or ME selector if needed | 174 | * Bits 24..33: The SE or ME selector if needed |
| 174 | * Bits 34..43: The SH (or SA) or PIPE selector if needed | 175 | * Bits 34..43: The SH (or SA) or PIPE selector if needed |
| 175 | * Bits 44..53: The INSTANCE (or CU/WGP) or QUEUE selector if needed | 176 | * Bits 44..53: The INSTANCE (or CU/WGP) or QUEUE selector if needed |
| 176 | * | 177 | * |
| 177 | * Bit 23: Indicates that the PM power gating lock should be held | 178 | * Bit 23: Indicates that the PM power gating lock should be held |
| 178 | * This is necessary to read registers that might be | 179 | * This is necessary to read registers that might be |
| 179 | * unreliable during a power gating transistion. | 180 | * unreliable during a power gating transistion. |
| 180 | * | 181 | * |
| 181 | * The lower bits are the BYTE offset of the register to read. This | 182 | * The lower bits are the BYTE offset of the register to read. This |
| 182 | * allows reading multiple registers in a single call and having | 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 | struct amdgpu_device *adev = f->f_inode->i_private; | 866 | struct amdgpu_device *adev = f->f_inode->i_private; |
| 866 | int r, x; | 867 | int r, x; |
| 867 | ssize_t result=0; | 868 | ssize_t result = 0; |
| 868 | uint32_t offset, se, sh, cu, wave, simd, data[32]; | 869 | uint32_t offset, se, sh, cu, wave, simd, data[32]; |
| 869 | 870 | ||
| 870 | if (size & 3 || *pos & 3) | 871 | if (size & 3 || *pos & 3) |
| @@ -1210,7 +1211,7 @@ static const char *debugfs_regs_names[] = { · 339 unmodified lines | |||
| 1210 | 1211 | ||
| 1211 | /** | 1212 | /** |
| 1212 | * amdgpu_debugfs_regs_init - Initialize debugfs entries that provide | 1213 | * amdgpu_debugfs_regs_init - Initialize debugfs entries that provide |
| 1213 | * register access. | 1214 | * register access. |
| 1214 | * | 1215 | * |
| 1215 | * @adev: The device to attach the debugfs entries to | 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 | return 0; | 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 | static const struct drm_info_list amdgpu_debugfs_list[] = { | 1371 | static const struct drm_info_list amdgpu_debugfs_list[] = { |
| 1342 | {"amdgpu_vbios", amdgpu_debugfs_get_vbios_dump}, | 1372 | {"amdgpu_vbios", amdgpu_debugfs_get_vbios_dump}, |
| 1343 | {"amdgpu_test_ib", &amdgpu_debugfs_test_ib}, | 1373 | {"amdgpu_test_ib", &amdgpu_debugfs_test_ib}, |
| 1344 | {"amdgpu_evict_vram", &amdgpu_debugfs_evict_vram}, | 1374 | {"amdgpu_evict_vram", &amdgpu_debugfs_evict_vram}, |
| 1345 | {"amdgpu_evict_gtt", &amdgpu_debugfs_evict_gtt}, | 1375 | {"amdgpu_evict_gtt", &amdgpu_debugfs_evict_gtt}, |
| 1376 | {"amdgpu_vm_info", &amdgpu_debugfs_vm_info}, | ||
| 1346 | }; | 1377 | }; |
| 1347 | 1378 | ||
| 1348 | static void amdgpu_ib_preempt_fences_swap(struct amdgpu_ring *ring, | 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 | amdgpu_rap_debugfs_init(adev); | 1670 | amdgpu_rap_debugfs_init(adev); |
| 1640 | 1671 | ||
| 1672 | amdgpu_fw_attestation_debugfs_init(adev); | ||
| 1673 | |||
| 1641 | return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_list, | 1674 | return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_list, |
| 1642 | ARRAY_SIZE(amdgpu_debugfs_list)); | 1675 | ARRAY_SIZE(amdgpu_debugfs_list)); |
| 1643 | } | 1676 | } |
| @@ -80,6 +80,8 @@ MODULE_FIRMWARE("amdgpu/renoir_gpu_info.bin"); · 79 unmodified lines | |||
| 80 | MODULE_FIRMWARE("amdgpu/navi10_gpu_info.bin"); | 80 | MODULE_FIRMWARE("amdgpu/navi10_gpu_info.bin"); |
| 81 | MODULE_FIRMWARE("amdgpu/navi14_gpu_info.bin"); | 81 | MODULE_FIRMWARE("amdgpu/navi14_gpu_info.bin"); |
| 82 | MODULE_FIRMWARE("amdgpu/navi12_gpu_info.bin"); | 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 | #define AMDGPU_RESUME_MS 2000 | 86 | #define AMDGPU_RESUME_MS 2000 |
| 85 | 87 | ||
| @@ -114,6 +116,8 @@ const char *amdgpu_asic_name[] = { · 28 unmodified lines | |||
| 114 | "NAVI12", | 116 | "NAVI12", |
| 115 | "SIENNA_CICHLID", | 117 | "SIENNA_CICHLID", |
| 116 | "NAVY_FLOUNDER", | 118 | "NAVY_FLOUNDER", |
| 119 | "VANGOGH", | ||
| 120 | "DIMGREY_CAVEFISH", | ||
| 117 | "LAST", | 121 | "LAST", |
| 118 | }; | 122 | }; |
| 119 | 123 | ||
| @@ -239,9 +243,11 @@ bool amdgpu_device_supports_baco(struct drm_device *dev) · 119 unmodified lines | |||
| 239 | return amdgpu_asic_supports_baco(adev); | 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 | * amdgpu_device_vram_access - read/write a buffer in vram | 251 | * amdgpu_device_vram_access - read/write a buffer in vram |
| 246 | * | 252 | * |
| 247 | * @adev: amdgpu_device pointer | 253 | * @adev: amdgpu_device pointer |
| @@ -705,7 +711,7 @@ void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev, · 457 unmodified lines | |||
| 705 | /** | 711 | /** |
| 706 | * amdgpu_invalid_rreg - dummy reg read function | 712 | * amdgpu_invalid_rreg - dummy reg read function |
| 707 | * | 713 | * |
| 708 | * @adev: amdgpu device pointer | 714 | * @adev: amdgpu_device pointer |
| 709 | * @reg: offset of register | 715 | * @reg: offset of register |
| 710 | * | 716 | * |
| 711 | * Dummy register read function. Used for register blocks | 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 | * amdgpu_invalid_wreg - dummy reg write function | 729 | * amdgpu_invalid_wreg - dummy reg write function |
| 724 | * | 730 | * |
| 725 | * @adev: amdgpu device pointer | 731 | * @adev: amdgpu_device pointer |
| 726 | * @reg: offset of register | 732 | * @reg: offset of register |
| 727 | * @v: value to write to the register | 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 | * amdgpu_invalid_rreg64 - dummy 64 bit reg read function | 746 | * amdgpu_invalid_rreg64 - dummy 64 bit reg read function |
| 741 | * | 747 | * |
| 742 | * @adev: amdgpu device pointer | 748 | * @adev: amdgpu_device pointer |
| 743 | * @reg: offset of register | 749 | * @reg: offset of register |
| 744 | * | 750 | * |
| 745 | * Dummy register read function. Used for register blocks | 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 | * amdgpu_invalid_wreg64 - dummy reg write function | 763 | * amdgpu_invalid_wreg64 - dummy reg write function |
| 758 | * | 764 | * |
| 759 | * @adev: amdgpu device pointer | 765 | * @adev: amdgpu_device pointer |
| 760 | * @reg: offset of register | 766 | * @reg: offset of register |
| 761 | * @v: value to write to the register | 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 | * amdgpu_block_invalid_rreg - dummy reg read function | 780 | * amdgpu_block_invalid_rreg - dummy reg read function |
| 775 | * | 781 | * |
| 776 | * @adev: amdgpu device pointer | 782 | * @adev: amdgpu_device pointer |
| 777 | * @block: offset of instance | 783 | * @block: offset of instance |
| 778 | * @reg: offset of register | 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 | * amdgpu_block_invalid_wreg - dummy reg write function | 800 | * amdgpu_block_invalid_wreg - dummy reg write function |
| 795 | * | 801 | * |
| 796 | * @adev: amdgpu device pointer | 802 | * @adev: amdgpu_device pointer |
| 797 | * @block: offset of instance | 803 | * @block: offset of instance |
| 798 | * @reg: offset of register | 804 | * @reg: offset of register |
| 799 | * @v: value to write to the register | 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 | * amdgpu_device_asic_init - Wrapper for atom asic_init | 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 | * Does any asic specific work and then calls atom asic init. | 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 | * amdgpu_device_vram_scratch_init - allocate the VRAM scratch page | 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 | * Allocates a scratch page of VRAM for use by various things in the | 838 | * Allocates a scratch page of VRAM for use by various things in the |
| 833 | * driver. | 839 | * driver. |
| @@ -844,7 +850,7 @@ static int amdgpu_device_vram_scratch_init(struct amdgpu_device *adev) · 10 unmodified lines | |||
| 844 | /** | 850 | /** |
| 845 | * amdgpu_device_vram_scratch_fini - Free the VRAM scratch page | 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 | * Frees the VRAM scratch page. | 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 | amdgpu_gmc_tmz_set(adev); | 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 | amdgpu_gmc_noretry_set(adev); | 1379 | amdgpu_gmc_noretry_set(adev); |
| 1381 | 1380 | ||
| 1382 | return 0; | 1381 | return 0; |
| @@ -1783,6 +1782,7 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev) · 400 unmodified lines | |||
| 1783 | case CHIP_VEGA20: | 1782 | case CHIP_VEGA20: |
| 1784 | case CHIP_SIENNA_CICHLID: | 1783 | case CHIP_SIENNA_CICHLID: |
| 1785 | case CHIP_NAVY_FLOUNDER: | 1784 | case CHIP_NAVY_FLOUNDER: |
| 1785 | case CHIP_DIMGREY_CAVEFISH: | ||
| 1786 | default: | 1786 | default: |
| 1787 | return 0; | 1787 | return 0; |
| 1788 | case CHIP_VEGA10: | 1788 | case CHIP_VEGA10: |
| @@ -1803,7 +1803,10 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev) · 14 unmodified lines | |||
| 1803 | chip_name = "arcturus"; | 1803 | chip_name = "arcturus"; |
| 1804 | break; | 1804 | break; |
| 1805 | case CHIP_RENOIR: | 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 | break; | 1810 | break; |
| 1808 | case CHIP_NAVI10: | 1811 | case CHIP_NAVI10: |
| 1809 | chip_name = "navi10"; | 1812 | chip_name = "navi10"; |
| @@ -1814,6 +1817,9 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev) · 4 unmodified lines | |||
| 1814 | case CHIP_NAVI12: | 1817 | case CHIP_NAVI12: |
| 1815 | chip_name = "navi12"; | 1818 | chip_name = "navi12"; |
| 1816 | break; | 1819 | break; |
| 1820 | case CHIP_VANGOGH: | ||
| 1821 | chip_name = "vangogh"; | ||
| 1822 | break; | ||
| 1817 | } | 1823 | } |
| 1818 | 1824 | ||
| 1819 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_gpu_info.bin", chip_name); | 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 | case CHIP_NAVI12: | 1994 | case CHIP_NAVI12: |
| 1989 | case CHIP_SIENNA_CICHLID: | 1995 | case CHIP_SIENNA_CICHLID: |
| 1990 | case CHIP_NAVY_FLOUNDER: | 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 | r = nv_set_ip_blocks(adev); | 2004 | r = nv_set_ip_blocks(adev); |
| 1994 | if (r) | 2005 | if (r) |
| @@ -2993,10 +3004,10 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) · 998 unmodified lines | |||
| 2993 | case CHIP_NAVI14: | 3004 | case CHIP_NAVI14: |
| 2994 | case CHIP_NAVI12: | 3005 | case CHIP_NAVI12: |
| 2995 | case CHIP_RENOIR: | 3006 | case CHIP_RENOIR: |
| 2996 | #endif | ||
| 2997 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 2998 | case CHIP_SIENNA_CICHLID: | 3007 | case CHIP_SIENNA_CICHLID: |
| 2999 | case CHIP_NAVY_FLOUNDER: | 3008 | case CHIP_NAVY_FLOUNDER: |
| 3009 | case CHIP_DIMGREY_CAVEFISH: | ||
| 3010 | case CHIP_VANGOGH: | ||
| 3000 | #endif | 3011 | #endif |
| 3001 | return amdgpu_dc != 0; | 3012 | return amdgpu_dc != 0; |
| 3002 | #endif | 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 | * amdgpu_device_has_dc_support - check if dc is supported | 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 | * Returns true for supported, false for not supported | 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 | * amdgpu_device_reset_sriov - reset ASIC for SR-IOV vf | 4057 | * amdgpu_device_reset_sriov - reset ASIC for SR-IOV vf |
| 4047 | * | 4058 | * |
| 4048 | * @adev: amdgpu device pointer | 4059 | * @adev: amdgpu_device pointer |
| 4049 | * @from_hypervisor: request from hypervisor | 4060 | * @from_hypervisor: request from hypervisor |
| 4050 | * | 4061 | * |
| 4051 | * do VF FLR and reinitialize Asic | 4062 | * do VF FLR and reinitialize Asic |
| @@ -4100,7 +4111,7 @@ error: · 48 unmodified lines | |||
| 4100 | /** | 4111 | /** |
| 4101 | * amdgpu_device_has_job_running - check if there is any job in mirror list | 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 | * check if there is any job in mirror list | 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 | * amdgpu_device_should_recover_gpu - check if we should try GPU recovery | 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 | * Check amdgpu_gpu_recovery and SRIOV status to see if we should try to recover | 4144 | * Check amdgpu_gpu_recovery and SRIOV status to see if we should try to recover |
| 4134 | * a hung GPU. | 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 | * amdgpu_device_gpu_recover - reset the asic and recover scheduler | 4489 | * amdgpu_device_gpu_recover - reset the asic and recover scheduler |
| 4479 | * | 4490 | * |
| 4480 | * @adev: amdgpu device pointer | 4491 | * @adev: amdgpu_device pointer |
| 4481 | * @job: which job trigger hang | 4492 | * @job: which job trigger hang |
| 4482 | * | 4493 | * |
| 4483 | * Attempt to reset the GPU if it has hung (all asics). | 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 | bool need_emergency_restart = false; | 4508 | bool need_emergency_restart = false; |
| 4498 | bool audio_suspended = false; | 4509 | bool audio_suspended = false; |
| 4499 | 4510 | ||
| 4500 | /** | 4511 | /* |
| 4501 | * Special case: RAS triggered and full reset isn't supported | 4512 | * Special case: RAS triggered and full reset isn't supported |
| 4502 | */ | 4513 | */ |
| 4503 | need_emergency_restart = amdgpu_ras_need_emergency_restart(adev); | 4514 | need_emergency_restart = amdgpu_ras_need_emergency_restart(adev); |
| @@ -44,11 +44,11 @@ struct amdgpu_df_funcs { · 43 unmodified lines | |||
| 44 | void (*enable_ecc_force_par_wr_rmw)(struct amdgpu_device *adev, | 44 | void (*enable_ecc_force_par_wr_rmw)(struct amdgpu_device *adev, |
| 45 | bool enable); | 45 | bool enable); |
| 46 | int (*pmc_start)(struct amdgpu_device *adev, uint64_t config, | 46 | int (*pmc_start)(struct amdgpu_device *adev, uint64_t config, |
| 47 | int is_add); | 47 | int counter_idx, int is_add); |
| 48 | int (*pmc_stop)(struct amdgpu_device *adev, uint64_t config, | 48 | int (*pmc_stop)(struct amdgpu_device *adev, uint64_t config, |
| 49 | int is_remove); | 49 | int counter_idx, int is_remove); |
| 50 | void (*pmc_get_count)(struct amdgpu_device *adev, uint64_t config, | 50 | void (*pmc_get_count)(struct amdgpu_device *adev, uint64_t config, |
| 51 | uint64_t *count); | 51 | int counter_idx, uint64_t *count); |
| 52 | uint64_t (*get_fica)(struct amdgpu_device *adev, uint32_t ficaa_val); | 52 | uint64_t (*get_fica)(struct amdgpu_device *adev, uint32_t ficaa_val); |
| 53 | void (*set_fica)(struct amdgpu_device *adev, uint32_t ficaa_val, | 53 | void (*set_fica)(struct amdgpu_device *adev, uint32_t ficaa_val, |
| 54 | uint32_t ficadl_val, uint32_t ficadh_val); | 54 | uint32_t ficadl_val, uint32_t ficadh_val); |
| @@ -38,6 +38,7 @@ · 37 unmodified lines | |||
| 38 | #include <drm/drm_edid.h> | 38 | #include <drm/drm_edid.h> |
| 39 | #include <drm/drm_gem_framebuffer_helper.h> | 39 | #include <drm/drm_gem_framebuffer_helper.h> |
| 40 | #include <drm/drm_fb_helper.h> | 40 | #include <drm/drm_fb_helper.h> |
| 41 | #include <drm/drm_fourcc.h> | ||
| 41 | #include <drm/drm_vblank.h> | 42 | #include <drm/drm_vblank.h> |
| 42 | 43 | ||
| 43 | static void amdgpu_display_flip_callback(struct dma_fence *f, | 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 | (adev->apu_flags & AMD_APU_IS_PICASSO)) | 525 | (adev->apu_flags & AMD_APU_IS_PICASSO)) |
| 525 | domain |= AMDGPU_GEM_DOMAIN_GTT; | 526 | domain |= AMDGPU_GEM_DOMAIN_GTT; |
| 526 | break; | 527 | break; |
| 528 | case CHIP_RENOIR: | ||
| 529 | domain |= AMDGPU_GEM_DOMAIN_GTT; | ||
| 530 | break; | ||
| 531 | |||
| 527 | default: | 532 | default: |
| 528 | break; | 533 | break; |
| 529 | } | 534 | } |
| @@ -533,6 +538,154 @@ uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev, · 3 unmodified lines | |||
| 533 | return domain; | 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 | int amdgpu_display_framebuffer_init(struct drm_device *dev, | 689 | int amdgpu_display_framebuffer_init(struct drm_device *dev, |
| 537 | struct amdgpu_framebuffer *rfb, | 690 | struct amdgpu_framebuffer *rfb, |
| 538 | const struct drm_mode_fb_cmd2 *mode_cmd, | 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 | rfb->base.obj[0] = obj; | 695 | rfb->base.obj[0] = obj; |
| 543 | drm_helper_mode_fill_fb_struct(dev, &rfb->base, mode_cmd); | 696 | drm_helper_mode_fill_fb_struct(dev, &rfb->base, mode_cmd); |
| 544 | ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs); | 697 | ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs); |
| 545 | if (ret) { | 698 | if (ret) |
| 546 | rfb->base.obj[0] = NULL; | 699 | goto fail; |
| 547 | return ret; | 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 | return 0; | 712 | return 0; |
| 713 | |||
| 714 | fail: | ||
| 715 | rfb->base.obj[0] = NULL; | ||
| 716 | return ret; | ||
| 550 | } | 717 | } |
| 551 | 718 | ||
| 552 | struct drm_framebuffer * | 719 | struct drm_framebuffer * |
| @@ -95,16 +95,16 @@ · 94 unmodified lines | |||
| 95 | #define KMS_DRIVER_MINOR 40 | 95 | #define KMS_DRIVER_MINOR 40 |
| 96 | #define KMS_DRIVER_PATCHLEVEL 0 | 96 | #define KMS_DRIVER_PATCHLEVEL 0 |
| 97 | 97 | ||
| 98 | int amdgpu_vram_limit = 0; | 98 | int amdgpu_vram_limit; |
| 99 | int amdgpu_vis_vram_limit = 0; | 99 | int amdgpu_vis_vram_limit; |
| 100 | int amdgpu_gart_size = -1; /* auto */ | 100 | int amdgpu_gart_size = -1; /* auto */ |
| 101 | int amdgpu_gtt_size = -1; /* auto */ | 101 | int amdgpu_gtt_size = -1; /* auto */ |
| 102 | int amdgpu_moverate = -1; /* auto */ | 102 | int amdgpu_moverate = -1; /* auto */ |
| 103 | int amdgpu_benchmarking = 0; | 103 | int amdgpu_benchmarking; |
| 104 | int amdgpu_testing = 0; | 104 | int amdgpu_testing; |
| 105 | int amdgpu_audio = -1; | 105 | int amdgpu_audio = -1; |
| 106 | int amdgpu_disp_priority = 0; | 106 | int amdgpu_disp_priority; |
| 107 | int amdgpu_hw_i2c = 0; | 107 | int amdgpu_hw_i2c; |
| 108 | int amdgpu_pcie_gen2 = -1; | 108 | int amdgpu_pcie_gen2 = -1; |
| 109 | int amdgpu_msi = -1; | 109 | int amdgpu_msi = -1; |
| 110 | char amdgpu_lockup_timeout[AMDGPU_MAX_TIMEOUT_PARAM_LENGTH]; | 110 | char amdgpu_lockup_timeout[AMDGPU_MAX_TIMEOUT_PARAM_LENGTH]; |
| @@ -114,19 +114,19 @@ int amdgpu_aspm = -1; · 3 unmodified lines | |||
| 114 | int amdgpu_runtime_pm = -1; | 114 | int amdgpu_runtime_pm = -1; |
| 115 | uint amdgpu_ip_block_mask = 0xffffffff; | 115 | uint amdgpu_ip_block_mask = 0xffffffff; |
| 116 | int amdgpu_bapm = -1; | 116 | int amdgpu_bapm = -1; |
| 117 | int amdgpu_deep_color = 0; | 117 | int amdgpu_deep_color; |
| 118 | int amdgpu_vm_size = -1; | 118 | int amdgpu_vm_size = -1; |
| 119 | int amdgpu_vm_fragment_size = -1; | 119 | int amdgpu_vm_fragment_size = -1; |
| 120 | int amdgpu_vm_block_size = -1; | 120 | int amdgpu_vm_block_size = -1; |
| 121 | int amdgpu_vm_fault_stop = 0; | 121 | int amdgpu_vm_fault_stop; |
| 122 | int amdgpu_vm_debug = 0; | 122 | int amdgpu_vm_debug; |
| 123 | int amdgpu_vm_update_mode = -1; | 123 | int amdgpu_vm_update_mode = -1; |
| 124 | int amdgpu_exp_hw_support = 0; | 124 | int amdgpu_exp_hw_support; |
| 125 | int amdgpu_dc = -1; | 125 | int amdgpu_dc = -1; |
| 126 | int amdgpu_sched_jobs = 32; | 126 | int amdgpu_sched_jobs = 32; |
| 127 | int amdgpu_sched_hw_submission = 2; | 127 | int amdgpu_sched_hw_submission = 2; |
| 128 | uint amdgpu_pcie_gen_cap = 0; | 128 | uint amdgpu_pcie_gen_cap; |
| 129 | uint amdgpu_pcie_lane_cap = 0; | 129 | uint amdgpu_pcie_lane_cap; |
| 130 | uint amdgpu_cg_mask = 0xffffffff; | 130 | uint amdgpu_cg_mask = 0xffffffff; |
| 131 | uint amdgpu_pg_mask = 0xffffffff; | 131 | uint amdgpu_pg_mask = 0xffffffff; |
| 132 | uint amdgpu_sdma_phase_quantum = 32; | 132 | uint amdgpu_sdma_phase_quantum = 32; |
| @@ -134,23 +134,31 @@ char *amdgpu_disable_cu = NULL; · 1 unmodified line | |||
| 134 | char *amdgpu_virtual_display = NULL; | 134 | char *amdgpu_virtual_display = NULL; |
| 135 | /* OverDrive(bit 14) disabled by default*/ | 135 | /* OverDrive(bit 14) disabled by default*/ |
| 136 | uint amdgpu_pp_feature_mask = 0xffffbfff; | 136 | uint amdgpu_pp_feature_mask = 0xffffbfff; |
| 137 | uint amdgpu_force_long_training = 0; | 137 | uint amdgpu_force_long_training; |
| 138 | int amdgpu_job_hang_limit = 0; | 138 | int amdgpu_job_hang_limit; |
| 139 | int amdgpu_lbpw = -1; | 139 | int amdgpu_lbpw = -1; |
| 140 | int amdgpu_compute_multipipe = -1; | 140 | int amdgpu_compute_multipipe = -1; |
| 141 | int amdgpu_gpu_recovery = -1; /* auto */ | 141 | int amdgpu_gpu_recovery = -1; /* auto */ |
| 142 | int amdgpu_emu_mode = 0; | 142 | int amdgpu_emu_mode; |
| 143 | uint amdgpu_smu_memory_pool_size = 0; | 143 | uint amdgpu_smu_memory_pool_size; |
| 144 | /* FBC (bit 0) disabled by default*/ | 144 | /* |
| 145 | uint amdgpu_dc_feature_mask = 0; | 145 | * FBC (bit 0) disabled by default |
| 146 | uint amdgpu_dc_debug_mask = 0; | 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 | int amdgpu_async_gfx_ring = 1; | 155 | int amdgpu_async_gfx_ring = 1; |
| 148 | int amdgpu_mcbp = 0; | 156 | int amdgpu_mcbp; |
| 149 | int amdgpu_discovery = -1; | 157 | int amdgpu_discovery = -1; |
| 150 | int amdgpu_mes = 0; | 158 | int amdgpu_mes; |
| 151 | int amdgpu_noretry = -1; | 159 | int amdgpu_noretry = -1; |
| 152 | int amdgpu_force_asic_type = -1; | 160 | int amdgpu_force_asic_type = -1; |
| 153 | int amdgpu_tmz = 0; | 161 | int amdgpu_tmz; |
| 154 | int amdgpu_reset_method = -1; /* auto */ | 162 | int amdgpu_reset_method = -1; /* auto */ |
| 155 | int amdgpu_num_kcq = -1; | 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 | * DOC: dpm (int) | 281 | * DOC: dpm (int) |
| 274 | * Override for dynamic power management setting | 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 | * The default is -1 (auto). | 284 | * The default is -1 (auto). |
| 277 | */ | 285 | */ |
| 278 | MODULE_PARM_DESC(dpm, "DPM support (1 = enable, 0 = disable, -1 = auto)"); | 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 | * Defaults to 0, or disabled. Userspace can still override this level later | 773 | * Defaults to 0, or disabled. Userspace can still override this level later |
| 766 | * after boot. | 774 | * after boot. |
| 767 | */ | 775 | */ |
| 768 | uint amdgpu_dm_abm_level = 0; | 776 | uint amdgpu_dm_abm_level; |
| 769 | MODULE_PARM_DESC(abmlevel, "ABM level (0 = off (default), 1-4 = backlight reduction level) "); | 777 | MODULE_PARM_DESC(abmlevel, "ABM level (0 = off (default), 1-4 = backlight reduction level) "); |
| 770 | module_param_named(abmlevel, amdgpu_dm_abm_level, uint, 0444); | 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 | {0x1002, 0x73AE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID}, | 1098 | {0x1002, 0x73AE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID}, |
| 1091 | {0x1002, 0x73BF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SIENNA_CICHLID}, | 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 | {0, 0, 0} | 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 | int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv) | 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 | if (!filp) | 1512 | if (!filp) |
| 1502 | return -EINVAL; | 1513 | return -EINVAL; |
| @@ -207,6 +207,7 @@ static int amdgpufb_create(struct drm_fb_helper *helper, · 206 unmodified lines | |||
| 207 | int ret; | 207 | int ret; |
| 208 | unsigned long tmp; | 208 | unsigned long tmp; |
| 209 | 209 | ||
| 210 | memset(&mode_cmd, 0, sizeof(mode_cmd)); | ||
| 210 | mode_cmd.width = sizes->surface_width; | 211 | mode_cmd.width = sizes->surface_width; |
| 211 | mode_cmd.height = sizes->surface_height; | 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 | #if defined(CONFIG_DEBUG_FS) | 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 | static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data) | 853 | static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data) |
| 915 | { | 854 | { |
| 916 | struct drm_info_node *node = (struct drm_info_node *)m->private; | 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 | list_for_each_entry(file, &dev->filelist, lhead) { | 864 | list_for_each_entry(file, &dev->filelist, lhead) { |
| 926 | struct task_struct *task; | 865 | struct task_struct *task; |
| 866 | struct drm_gem_object *gobj; | ||
| 867 | int id; | ||
| 927 | 868 | ||
| 928 | /* | 869 | /* |
| 929 | * Although we have a valid reference on file->pid, that does | 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 | rcu_read_unlock(); | 879 | rcu_read_unlock(); |
| 939 | 880 | ||
| 940 | spin_lock(&file->table_lock); | 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 | spin_unlock(&file->table_lock); | 887 | spin_unlock(&file->table_lock); |
| 943 | } | 888 | } |
| 944 | 889 | ||
| @@ -804,3 +804,14 @@ failed_undo: · 803 unmodified lines | |||
| 804 | failed_kiq_write: | 804 | failed_kiq_write: |
| 805 | dev_err(adev->dev, "failed to write reg:%x\n", reg); | 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 | void (*reset_ras_error_count) (struct amdgpu_device *adev); | 218 | void (*reset_ras_error_count) (struct amdgpu_device *adev); |
| 219 | void (*init_spm_golden)(struct amdgpu_device *adev); | 219 | void (*init_spm_golden)(struct amdgpu_device *adev); |
| 220 | void (*query_ras_error_status) (struct amdgpu_device *adev); | 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 | struct sq_work { | 224 | struct sq_work { |
| @@ -392,4 +393,5 @@ int amdgpu_gfx_cp_ecc_error_irq(struct amdgpu_device *adev, · 168 unmodified lines | |||
| 392 | struct amdgpu_iv_entry *entry); | 393 | struct amdgpu_iv_entry *entry); |
| 393 | uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg); | 394 | uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg); |
| 394 | void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v); | 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 | #endif | 397 | #endif |
| @@ -389,6 +389,7 @@ void amdgpu_gmc_tmz_set(struct amdgpu_device *adev) · 388 unmodified lines | |||
| 389 | case CHIP_NAVI10: | 389 | case CHIP_NAVI10: |
| 390 | case CHIP_NAVI14: | 390 | case CHIP_NAVI14: |
| 391 | case CHIP_NAVI12: | 391 | case CHIP_NAVI12: |
| 392 | case CHIP_VANGOGH: | ||
| 392 | /* Don't enable it by default yet. | 393 | /* Don't enable it by default yet. |
| 393 | */ | 394 | */ |
| 394 | if (amdgpu_tmz < 1) { | 395 | if (amdgpu_tmz < 1) { |
| @@ -421,20 +422,30 @@ void amdgpu_gmc_noretry_set(struct amdgpu_device *adev) · 26 unmodified lines | |||
| 421 | struct amdgpu_gmc *gmc = &adev->gmc; | 422 | struct amdgpu_gmc *gmc = &adev->gmc; |
| 422 | 423 | ||
| 423 | switch (adev->asic_type) { | 424 | switch (adev->asic_type) { |
| 424 | case CHIP_RAVEN: | 425 | case CHIP_VEGA20: |
| 425 | /* Raven currently has issues with noretry | 426 | case CHIP_NAVI10: |
| 426 | * regardless of what we decide for other | 427 | case CHIP_NAVI14: |
| 427 | * asics, we should leave raven with | 428 | case CHIP_SIENNA_CICHLID: |
| 428 | * noretry = 0 until we root cause the | 429 | case CHIP_NAVY_FLOUNDER: |
| 429 | * issues. | 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 | if (amdgpu_noretry == -1) | 435 | if (amdgpu_noretry == -1) |
| 432 | gmc->noretry = 0; | 436 | gmc->noretry = 1; |
| 433 | else | 437 | else |
| 434 | gmc->noretry = amdgpu_noretry; | 438 | gmc->noretry = amdgpu_noretry; |
| 435 | break; | 439 | break; |
| 440 | case CHIP_RAVEN: | ||
| 436 | default: | 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 | * to change this in the future for certain | 449 | * to change this in the future for certain |
| 439 | * GPUs as it can increase performance in | 450 | * GPUs as it can increase performance in |
| 440 | * certain cases. | 451 | * certain cases. |
| @@ -81,8 +81,8 @@ static const struct ttm_resource_manager_func amdgpu_gtt_mgr_func; · 80 unmodified lines | |||
| 81 | /** | 81 | /** |
| 82 | * amdgpu_gtt_mgr_init - init GTT manager and DRM MM | 82 | * amdgpu_gtt_mgr_init - init GTT manager and DRM MM |
| 83 | * | 83 | * |
| 84 | * @man: TTM memory type manager | 84 | * @adev: amdgpu_device pointer |
| 85 | * @p_size: maximum size of GTT | 85 | * @gtt_size: maximum size of GTT |
| 86 | * | 86 | * |
| 87 | * Allocate and initialize the GTT manager. | 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 | * amdgpu_gtt_mgr_fini - free and destroy GTT manager | 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 | * Destroy and free the GTT manager, returns -EBUSY if ranges are still | 128 | * Destroy and free the GTT manager, returns -EBUSY if ranges are still |
| 129 | * allocated inside it. | 129 | * allocated inside it. |
| @@ -324,6 +324,10 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info, · 323 unmodified lines | |||
| 324 | fw_info->ver = adev->dm.dmcub_fw_version; | 324 | fw_info->ver = adev->dm.dmcub_fw_version; |
| 325 | fw_info->feature = 0; | 325 | fw_info->feature = 0; |
| 326 | break; | 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 | default: | 331 | default: |
| 328 | return -EINVAL; | 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 | seq_printf(m, "DMCUB feature version: %u, firmware version: 0x%08x\n", | 1448 | seq_printf(m, "DMCUB feature version: %u, firmware version: 0x%08x\n", |
| 1445 | fw_info.feature, fw_info.ver); | 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 | seq_printf(m, "VBIOS version: %s\n", ctx->vbios_version); | 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 | struct amdgpu_framebuffer { | 302 | struct amdgpu_framebuffer { |
| 303 | struct drm_framebuffer base; | 303 | struct drm_framebuffer base; |
| 304 | 304 | ||
| 305 | uint64_t tiling_flags; | ||
| 306 | bool tmz_surface; | ||
| 307 | |||
| 305 | /* caching for later use */ | 308 | /* caching for later use */ |
| 306 | uint64_t address; | 309 | uint64_t address; |
| 307 | }; | 310 | }; |
| @@ -53,6 +53,8 @@ struct amdgpu_nbio_funcs { · 52 unmodified lines | |||
| 53 | u32 (*get_hdp_flush_done_offset)(struct amdgpu_device *adev); | 53 | u32 (*get_hdp_flush_done_offset)(struct amdgpu_device *adev); |
| 54 | u32 (*get_pcie_index_offset)(struct amdgpu_device *adev); | 54 | u32 (*get_pcie_index_offset)(struct amdgpu_device *adev); |
| 55 | u32 (*get_pcie_data_offset)(struct amdgpu_device *adev); | 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 | u32 (*get_rev_id)(struct amdgpu_device *adev); | 58 | u32 (*get_rev_id)(struct amdgpu_device *adev); |
| 57 | void (*mc_access_enable)(struct amdgpu_device *adev, bool enable); | 59 | void (*mc_access_enable)(struct amdgpu_device *adev, bool enable); |
| 58 | void (*hdp_flush)(struct amdgpu_device *adev, struct amdgpu_ring *ring); | 60 | void (*hdp_flush)(struct amdgpu_device *adev, struct amdgpu_ring *ring); |
| @@ -85,6 +87,8 @@ struct amdgpu_nbio_funcs { · 26 unmodified lines | |||
| 85 | void (*query_ras_error_count)(struct amdgpu_device *adev, | 87 | void (*query_ras_error_count)(struct amdgpu_device *adev, |
| 86 | void *ras_error_status); | 88 | void *ras_error_status); |
| 87 | int (*ras_late_init)(struct amdgpu_device *adev); | 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 | struct amdgpu_nbio { | 94 | struct amdgpu_nbio { |
| @@ -1045,6 +1045,7 @@ static const char *amdgpu_vram_names[] = { · 1044 unmodified lines | |||
| 1045 | "DDR3", | 1045 | "DDR3", |
| 1046 | "DDR4", | 1046 | "DDR4", |
| 1047 | "GDDR6", | 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 | return domain; | 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 | #if defined(CONFIG_DEBUG_FS) | 328 | #if defined(CONFIG_DEBUG_FS) |
| 329 | void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager, | 329 | void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager, |
| 330 | struct seq_file *m); | 330 | struct seq_file *m); |
| 331 | u64 amdgpu_bo_print_info(int id, struct amdgpu_bo *bo, struct seq_file *m); | ||
| 331 | #endif | 332 | #endif |
| 332 | int amdgpu_debugfs_sa_init(struct amdgpu_device *adev); | 333 | int amdgpu_debugfs_sa_init(struct amdgpu_device *adev); |
| 333 | 334 | ||
| @@ -19,17 +19,29 @@ · 18 unmodified lines | |||
| 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| 20 | * OTHER DEALINGS IN THE SOFTWARE. | 20 | * OTHER DEALINGS IN THE SOFTWARE. |
| 21 | * | 21 | * |
| 22 | * Author: Jonathan Kim <jonathan.kim@amd.com> | ||
| 23 | * | ||
| 24 | */ | 22 | */ |
| 25 | 23 | ||
| 26 | #include <linux/perf_event.h> | 24 | #include <linux/perf_event.h> |
| 27 | #include <linux/init.h> | 25 | #include <linux/init.h> |
| 28 | #include "amdgpu.h" | 26 | #include "amdgpu.h" |
| 29 | #include "amdgpu_pmu.h" | 27 | #include "amdgpu_pmu.h" |
| 30 | #include "df_v3_6.h" | ||
| 31 | 28 | ||
| 32 | #define PMU_NAME_SIZE 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 | /* record to keep track of pmu entry per pmu type per device */ | 46 | /* record to keep track of pmu entry per pmu type per device */ |
| 35 | struct amdgpu_pmu_entry { | 47 | struct amdgpu_pmu_entry { |
| @@ -37,11 +49,162 @@ struct amdgpu_pmu_entry { · 1 unmodified line | |||
| 37 | struct amdgpu_device *adev; | 49 | struct amdgpu_device *adev; |
| 38 | struct pmu pmu; | 50 | struct pmu pmu; |
| 39 | unsigned int pmu_perf_type; | 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 | static LIST_HEAD(amdgpu_pmu_list); | 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 | /* initialize perf counter */ | 208 | /* initialize perf counter */ |
| 46 | static int amdgpu_perf_event_init(struct perf_event *event) | 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 | /* update the hw_perf_event struct with config data */ | 217 | /* update the hw_perf_event struct with config data */ |
| 55 | hwc->config = event->attr.config; | 218 | hwc->config = event->attr.config; |
| 219 | hwc->config_base = AMDGPU_PMU_PERF_TYPE_NONE; | ||
| 56 | 220 | ||
| 57 | return 0; | 221 | return 0; |
| 58 | } | 222 | } |
| @@ -64,6 +228,7 @@ static void amdgpu_perf_start(struct perf_event *event, int flags) · 5 unmodified lines | |||
| 64 | struct amdgpu_pmu_entry *pe = container_of(event->pmu, | 228 | struct amdgpu_pmu_entry *pe = container_of(event->pmu, |
| 65 | struct amdgpu_pmu_entry, | 229 | struct amdgpu_pmu_entry, |
| 66 | pmu); | 230 | pmu); |
| 231 | int target_cntr = 0; | ||
| 67 | 232 | ||
| 68 | if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED))) | 233 | if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED))) |
| 69 | return; | 234 | return; |
| @@ -71,19 +236,27 @@ static void amdgpu_perf_start(struct perf_event *event, int flags) · 1 unmodified line | |||
| 71 | WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE)); | 236 | WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE)); |
| 72 | hwc->state = 0; | 237 | hwc->state = 0; |
| 73 | 238 | ||
| 74 | switch (pe->pmu_perf_type) { | 239 | switch (hwc->config_base) { |
| 75 | case PERF_TYPE_AMDGPU_DF: | 240 | case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: |
| 76 | if (!(flags & PERF_EF_RELOAD)) | 241 | case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: |
| 77 | pe->adev->df.funcs->pmc_start(pe->adev, hwc->config, 1); | 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 | break; | 254 | break; |
| 81 | default: | 255 | default: |
| 82 | break; | 256 | break; |
| 83 | } | 257 | } |
| 84 | 258 | ||
| 85 | perf_event_update_userpage(event); | 259 | perf_event_update_userpage(event); |
| 86 | |||
| 87 | } | 260 | } |
| 88 | 261 | ||
| 89 | /* read perf counter */ | 262 | /* read perf counter */ |
| @@ -93,16 +266,16 @@ static void amdgpu_perf_read(struct perf_event *event) · 3 unmodified lines | |||
| 93 | struct amdgpu_pmu_entry *pe = container_of(event->pmu, | 266 | struct amdgpu_pmu_entry *pe = container_of(event->pmu, |
| 94 | struct amdgpu_pmu_entry, | 267 | struct amdgpu_pmu_entry, |
| 95 | pmu); | 268 | pmu); |
| 96 | |||
| 97 | u64 count, prev; | 269 | u64 count, prev; |
| 98 | 270 | ||
| 99 | do { | 271 | do { |
| 100 | prev = local64_read(&hwc->prev_count); | 272 | prev = local64_read(&hwc->prev_count); |
| 101 | 273 | ||
| 102 | switch (pe->pmu_perf_type) { | 274 | switch (hwc->config_base) { |
| 103 | case PERF_TYPE_AMDGPU_DF: | 275 | case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: |
| 104 | pe->adev->df.funcs->pmc_get_count(pe->adev, hwc->config, | 276 | case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: |
| 105 | &count); | 277 | pe->adev->df.funcs->pmc_get_count(pe->adev, |
| 278 | hwc->config, hwc->idx, &count); | ||
| 106 | break; | 279 | break; |
| 107 | default: | 280 | default: |
| 108 | count = 0; | 281 | count = 0; |
| @@ -124,9 +297,11 @@ static void amdgpu_perf_stop(struct perf_event *event, int flags) · 15 unmodified lines | |||
| 124 | if (hwc->state & PERF_HES_UPTODATE) | 297 | if (hwc->state & PERF_HES_UPTODATE) |
| 125 | return; | 298 | return; |
| 126 | 299 | ||
| 127 | switch (pe->pmu_perf_type) { | 300 | switch (hwc->config_base) { |
| 128 | case PERF_TYPE_AMDGPU_DF: | 301 | case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: |
| 129 | pe->adev->df.funcs->pmc_stop(pe->adev, hwc->config, 0); | 302 | case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: |
| 303 | pe->adev->df.funcs->pmc_stop(pe->adev, hwc->config, hwc->idx, | ||
| 304 | 0); | ||
| 130 | break; | 305 | break; |
| 131 | default: | 306 | default: |
| 132 | break; | 307 | break; |
| @@ -142,22 +317,39 @@ static void amdgpu_perf_stop(struct perf_event *event, int flags) · 9 unmodified lines | |||
| 142 | hwc->state |= PERF_HES_UPTODATE; | 317 | hwc->state |= PERF_HES_UPTODATE; |
| 143 | } | 318 | } |
| 144 | 319 | ||
| 145 | /* add perf counter */ | 320 | /* add perf counter */ |
| 146 | static int amdgpu_perf_add(struct perf_event *event, int flags) | 321 | static int amdgpu_perf_add(struct perf_event *event, int flags) |
| 147 | { | 322 | { |
| 148 | struct hw_perf_event *hwc = &event->hw; | 323 | struct hw_perf_event *hwc = &event->hw; |
| 149 | int retval; | 324 | int retval = 0, target_cntr; |
| 150 | |||
| 151 | struct amdgpu_pmu_entry *pe = container_of(event->pmu, | 325 | struct amdgpu_pmu_entry *pe = container_of(event->pmu, |
| 152 | struct amdgpu_pmu_entry, | 326 | struct amdgpu_pmu_entry, |
| 153 | pmu); | 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 | event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED; | 340 | event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED; |
| 156 | 341 | ||
| 157 | switch (pe->pmu_perf_type) { | 342 | switch (hwc->config_base) { |
| 158 | case PERF_TYPE_AMDGPU_DF: | 343 | case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: |
| 159 | retval = pe->adev->df.funcs->pmc_start(pe->adev, | 344 | case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: |
| 160 | hwc->config, 1); | 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 | break; | 353 | break; |
| 162 | default: | 354 | default: |
| 163 | return 0; | 355 | return 0; |
| @@ -170,7 +362,6 @@ static int amdgpu_perf_add(struct perf_event *event, int flags) · 6 unmodified lines | |||
| 170 | amdgpu_perf_start(event, PERF_EF_RELOAD); | 362 | amdgpu_perf_start(event, PERF_EF_RELOAD); |
| 171 | 363 | ||
| 172 | return retval; | 364 | return retval; |
| 173 | |||
| 174 | } | 365 | } |
| 175 | 366 | ||
| 176 | /* delete perf counter */ | 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 | amdgpu_perf_stop(event, PERF_EF_UPDATE); | 375 | amdgpu_perf_stop(event, PERF_EF_UPDATE); |
| 185 | 376 | ||
| 186 | switch (pe->pmu_perf_type) { | 377 | switch (hwc->config_base) { |
| 187 | case PERF_TYPE_AMDGPU_DF: | 378 | case AMDGPU_PMU_EVENT_CONFIG_TYPE_DF: |
| 188 | pe->adev->df.funcs->pmc_stop(pe->adev, hwc->config, 1); | 379 | case AMDGPU_PMU_EVENT_CONFIG_TYPE_XGMI: |
| 380 | pe->adev->df.funcs->pmc_stop(pe->adev, hwc->config, hwc->idx, | ||
| 381 | 1); | ||
| 189 | break; | 382 | break; |
| 190 | default: | 383 | default: |
| 191 | break; | 384 | break; |
| @@ -194,25 +387,92 @@ static void amdgpu_perf_del(struct perf_event *event, int flags) · 2 unmodified lines | |||
| 194 | perf_event_update_userpage(event); | 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 */ | 414 | static void amdgpu_pmu_create_attrs(struct attribute_group *attr_group, |
| 200 | static int init_pmu_by_type(struct amdgpu_device *adev, | 415 | struct amdgpu_pmu_event_attribute *pmu_attr, |
| 201 | const struct attribute_group *attr_groups[], | 416 | struct amdgpu_pmu_attr events[], |
| 202 | char *pmu_type_name, char *pmu_file_prefix, | 417 | int num_events) |
| 203 | unsigned int pmu_perf_type, | ||
| 204 | unsigned int num_counters) | ||
| 205 | { | 418 | { |
| 206 | char pmu_name[PMU_NAME_SIZE]; | 419 | amdgpu_pmu_create_event_attrs_by_type(attr_group, pmu_attr, events, 0, |
| 207 | struct amdgpu_pmu_entry *pmu_entry; | 420 | num_events, AMDGPU_PMU_EVENT_CONFIG_TYPE_NONE); |
| 208 | int ret = 0; | 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 | return -ENOMEM; | 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 | pmu_entry->pmu = (struct pmu){ | 476 | pmu_entry->pmu = (struct pmu){ |
| 217 | .event_init = amdgpu_perf_event_init, | 477 | .event_init = amdgpu_perf_event_init, |
| 218 | .add = amdgpu_perf_add, | 478 | .add = amdgpu_perf_add, |
| @@ -223,59 +483,178 @@ static int init_pmu_by_type(struct amdgpu_device *adev, · 4 unmodified lines | |||
| 223 | .task_ctx_nr = perf_invalid_context, | 483 | .task_ctx_nr = perf_invalid_context, |
| 224 | }; | 484 | }; |
| 225 | 485 | ||
| 226 | pmu_entry->pmu.attr_groups = attr_groups; | 486 | ret = amdgpu_pmu_alloc_pmu_attrs(&pmu_entry->fmt_attr_group, |
| 227 | pmu_entry->pmu_perf_type = pmu_perf_type; | 487 | &pmu_entry->fmt_attr, |
| 228 | snprintf(pmu_name, PMU_NAME_SIZE, "%s_%d", | 488 | &pmu_entry->evt_attr_group, |
| 229 | pmu_file_prefix, adev_to_drm(adev)->primary->index); | 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 | ret = perf_pmu_register(&pmu_entry->pmu, pmu_name, -1); | 528 | ret = perf_pmu_register(&pmu_entry->pmu, pmu_name, -1); |
| 232 | 529 | ||
| 233 | if (ret) { | 530 | if (ret) |
| 234 | kfree(pmu_entry); | 531 | goto err_register; |
| 235 | pr_warn("Error initializing AMDGPU %s PMUs.\n", pmu_type_name); | 532 | |
| 236 | return ret; | 533 | if (pmu_entry->pmu_perf_type != AMDGPU_PMU_PERF_TYPE_ALL) |
| 237 | } | 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 | list_add_tail(&pmu_entry->entry, &amdgpu_pmu_list); | 540 | list_add_tail(&pmu_entry->entry, &amdgpu_pmu_list); |
| 243 | 541 | ||
| 244 | return 0; | 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 | /* init amdgpu_pmu */ | 599 | /* init amdgpu_pmu */ |
| 248 | int amdgpu_pmu_init(struct amdgpu_device *adev) | 600 | int amdgpu_pmu_init(struct amdgpu_device *adev) |
| 249 | { | 601 | { |
| 250 | int ret = 0; | 602 | int ret = 0; |
| 603 | struct amdgpu_pmu_entry *pmu_entry, *pmu_entry_df; | ||
| 251 | 604 | ||
| 252 | switch (adev->asic_type) { | 605 | switch (adev->asic_type) { |
| 253 | case CHIP_VEGA20: | 606 | case CHIP_VEGA20: |
| 254 | /* init df */ | 607 | pmu_entry_df = create_pmu_entry(adev, AMDGPU_PMU_PERF_TYPE_DF, |
| 255 | ret = init_pmu_by_type(adev, df_v3_6_attr_groups, | 608 | "DF", "amdgpu_df"); |
| 256 | "DF", "amdgpu_df", PERF_TYPE_AMDGPU_DF, | ||
| 257 | DF_V3_6_MAX_COUNTERS); | ||
| 258 | 609 | ||
| 259 | /* other pmu types go here*/ | 610 | if (!pmu_entry_df) |
| 260 | break; | 611 | return -ENOMEM; |
| 261 | default: | ||
| 262 | return 0; | ||
| 263 | } | ||
| 264 | 612 | ||
| 265 | return 0; | 613 | ret = init_pmu_entry_by_type_and_add(pmu_entry_df, |
| 266 | } | 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 */ | 621 | pmu_entry = create_pmu_entry(adev, AMDGPU_PMU_PERF_TYPE_ALL, |
| 270 | void amdgpu_pmu_fini(struct amdgpu_device *adev) | 622 | "", "amdgpu"); |
| 271 | { | ||
| 272 | struct amdgpu_pmu_entry *pe, *temp; | ||
| 273 | 623 | ||
| 274 | list_for_each_entry_safe(pe, temp, &amdgpu_pmu_list, entry) { | 624 | if (!pmu_entry) { |
| 275 | if (pe->adev == adev) { | 625 | amdgpu_pmu_fini(adev); |
| 276 | list_del(&pe->entry); | 626 | return -ENOMEM; |
| 277 | perf_pmu_unregister(&pe->pmu); | 627 | } |
| 278 | kfree(pe); | 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 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| 20 | * OTHER DEALINGS IN THE SOFTWARE. | 20 | * OTHER DEALINGS IN THE SOFTWARE. |
| 21 | * | 21 | * |
| 22 | * Author: Jonathan Kim <jonathan.kim@amd.com> | ||
| 23 | * | ||
| 24 | */ | 22 | */ |
| 25 | 23 | ||
| 26 | #ifndef _AMDGPU_PMU_H_ | 24 | #ifndef _AMDGPU_PMU_H_ |
| 27 | #define _AMDGPU_PMU_H_ | 25 | #define _AMDGPU_PMU_H_ |
| 28 | 26 | ||
| 27 | /* PMU types. */ | ||
| 29 | enum amdgpu_pmu_perf_type { | 28 | enum amdgpu_pmu_perf_type { |
| 30 | PERF_TYPE_AMDGPU_DF = 0, | 29 | AMDGPU_PMU_PERF_TYPE_NONE = 0, |
| 31 | PERF_TYPE_AMDGPU_MAX | 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 | int amdgpu_pmu_init(struct amdgpu_device *adev); | 54 | int amdgpu_pmu_init(struct amdgpu_device *adev); |
| 35 | void amdgpu_pmu_fini(struct amdgpu_device *adev); | 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 | case CHIP_NAVI12: | 100 | case CHIP_NAVI12: |
| 101 | case CHIP_SIENNA_CICHLID: | 101 | case CHIP_SIENNA_CICHLID: |
| 102 | case CHIP_NAVY_FLOUNDER: | 102 | case CHIP_NAVY_FLOUNDER: |
| 103 | case CHIP_VANGOGH: | ||
| 104 | case CHIP_DIMGREY_CAVEFISH: | ||
| 103 | psp_v11_0_set_psp_funcs(psp); | 105 | psp_v11_0_set_psp_funcs(psp); |
| 104 | psp->autoload_supported = true; | 106 | psp->autoload_supported = true; |
| 105 | break; | 107 | break; |
| @@ -288,6 +290,8 @@ psp_cmd_submit_buf(struct psp_context *psp, · 182 unmodified lines | |||
| 288 | skip_unsupport = (psp->cmd_buf_mem->resp.status == TEE_ERROR_NOT_SUPPORTED || | 290 | skip_unsupport = (psp->cmd_buf_mem->resp.status == TEE_ERROR_NOT_SUPPORTED || |
| 289 | psp->cmd_buf_mem->resp.status == PSP_ERR_UNKNOWN_COMMAND) && amdgpu_sriov_vf(psp->adev); | 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 | /* In some cases, psp response status is not 0 even there is no | 295 | /* In some cases, psp response status is not 0 even there is no |
| 292 | * problem while the command is submitted. Some version of PSP FW | 296 | * problem while the command is submitted. Some version of PSP FW |
| 293 | * doesn't write 0 to that field. | 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 | if (ucode) { | 315 | if (ucode) { |
| 315 | ucode->tmr_mc_addr_lo = psp->cmd_buf_mem->resp.fw_addr_lo; | 316 | ucode->tmr_mc_addr_lo = psp->cmd_buf_mem->resp.fw_addr_lo; |
| 316 | ucode->tmr_mc_addr_hi = psp->cmd_buf_mem->resp.fw_addr_hi; | 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 | return 0; | 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 | static void psp_prep_asd_load_cmd_buf(struct psp_gfx_cmd_resp *cmd, | 544 | static void psp_prep_asd_load_cmd_buf(struct psp_gfx_cmd_resp *cmd, |
| 513 | uint64_t asd_mc, uint32_t size) | 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 | uint64_t ta_shared_mc, | 656 | uint64_t ta_shared_mc, |
| 625 | uint32_t ta_shared_size) | 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 | cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(ta_bin_mc); | 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); | 661 | 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; | 662 | cmd->cmd.cmd_load_ta.app_len = ta_bin_size; |
| 631 | 663 | ||
| 632 | cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(ta_shared_mc); | 664 | cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(ta_shared_mc); |
| 633 | cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(ta_shared_mc); | 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 | static int psp_xgmi_init_shared_buf(struct psp_context *psp) | 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 | uint32_t ta_cmd_id, | 687 | uint32_t ta_cmd_id, |
| 656 | uint32_t session_id) | 688 | uint32_t session_id) |
| 657 | { | 689 | { |
| 658 | cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD; | 690 | cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD; |
| 659 | cmd->cmd.cmd_invoke_cmd.session_id = session_id; | 691 | cmd->cmd.cmd_invoke_cmd.session_id = session_id; |
| 660 | cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id; | 692 | cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id; |
| 661 | } | 693 | } |
| 662 | 694 | ||
| 663 | static int psp_ta_invoke(struct psp_context *psp, | 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 | struct ta_xgmi_shared_memory *xgmi_cmd; | 838 | struct ta_xgmi_shared_memory *xgmi_cmd; |
| 807 | int ret; | 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 | memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); | 842 | memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); |
| 811 | 843 | ||
| 812 | xgmi_cmd->cmd_id = TA_COMMAND_XGMI__GET_HIVE_ID; | 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 | struct ta_xgmi_shared_memory *xgmi_cmd; | 858 | struct ta_xgmi_shared_memory *xgmi_cmd; |
| 827 | int ret; | 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 | memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); | 862 | memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); |
| 831 | 863 | ||
| 832 | xgmi_cmd->cmd_id = TA_COMMAND_XGMI__GET_NODE_ID; | 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 | if (!topology || topology->num_nodes > TA_XGMI__MAX_CONNECTED_NODES) | 886 | if (!topology || topology->num_nodes > TA_XGMI__MAX_CONNECTED_NODES) |
| 855 | return -EINVAL; | 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 | memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); | 890 | memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); |
| 859 | 891 | ||
| 860 | /* Fill in the shared memory with topology information as input */ | 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 | if (!topology || topology->num_nodes > TA_XGMI__MAX_CONNECTED_NODES) | 930 | if (!topology || topology->num_nodes > TA_XGMI__MAX_CONNECTED_NODES) |
| 899 | return -EINVAL; | 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 | memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); | 934 | memset(xgmi_cmd, 0, sizeof(struct ta_xgmi_shared_memory)); |
| 903 | 935 | ||
| 904 | topology_info_input = &xgmi_cmd->xgmi_in_message.get_topology_info; | 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 | ret = psp_cmd_submit_buf(psp, NULL, cmd, | 994 | ret = psp_cmd_submit_buf(psp, NULL, cmd, |
| 963 | psp->fence_buf_mc_addr); | 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 | if (!ret) { | 999 | if (!ret) { |
| 968 | psp->ras.session_id = cmd->resp.session_id; | 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 | static int psp_load_smu_fw(struct psp_context *psp) | 1916 | static int psp_load_smu_fw(struct psp_context *psp) |
| 1885 | { | 1917 | { |
| 1886 | int ret; | 1918 | int ret; |
| 1887 | struct amdgpu_device* adev = psp->adev; | 1919 | struct amdgpu_device *adev = psp->adev; |
| 1888 | struct amdgpu_firmware_info *ucode = | 1920 | struct amdgpu_firmware_info *ucode = |
| 1889 | &adev->firmware.ucode[AMDGPU_UCODE_ID_SMC]; | 1921 | &adev->firmware.ucode[AMDGPU_UCODE_ID_SMC]; |
| 1890 | struct amdgpu_ras *ras = psp->ras.ras; | 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 | int i, ret; | 1983 | int i, ret; |
| 1952 | struct amdgpu_firmware_info *ucode; | 1984 | struct amdgpu_firmware_info *ucode; |
| 1953 | struct amdgpu_device* adev = psp->adev; | 1985 | struct amdgpu_device *adev = psp->adev; |
| 1954 | 1986 | ||
| 1955 | if (psp->autoload_supported && | 1987 | if (psp->autoload_supported && |
| 1956 | !psp->pmfw_centralized_cstate_management) { | 1988 | !psp->pmfw_centralized_cstate_management) { |
| @@ -1974,8 +2006,8 @@ static int psp_np_fw_load(struct psp_context *psp) · 17 unmodified lines | |||
| 1974 | continue; | 2006 | continue; |
| 1975 | 2007 | ||
| 1976 | if (psp->autoload_supported && | 2008 | if (psp->autoload_supported && |
| 1977 | (adev->asic_type == CHIP_SIENNA_CICHLID || | 2009 | (adev->asic_type >= CHIP_SIENNA_CICHLID && |
| 1978 | adev->asic_type == CHIP_NAVY_FLOUNDER) && | 2010 | adev->asic_type <= CHIP_DIMGREY_CAVEFISH) && |
| 1979 | (ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1 || | 2011 | (ucode->ucode_id == AMDGPU_UCODE_ID_SDMA1 || |
| 1980 | ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2 || | 2012 | ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2 || |
| 1981 | ucode->ucode_id == AMDGPU_UCODE_ID_SDMA3)) | 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 | const char *chip_name) | 2422 | const char *chip_name) |
| 2391 | { | 2423 | { |
| 2392 | struct amdgpu_device *adev = psp->adev; | 2424 | struct amdgpu_device *adev = psp->adev; |
| 2393 | char fw_name[30]; | 2425 | char fw_name[PSP_FW_NAME_LEN]; |
| 2394 | const struct psp_firmware_header_v1_0 *asd_hdr; | 2426 | const struct psp_firmware_header_v1_0 *asd_hdr; |
| 2395 | int err = 0; | 2427 | int err = 0; |
| 2396 | 2428 | ||
| @@ -2422,11 +2454,47 @@ out: · 25 unmodified lines | |||
| 2422 | return err; | 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 | const char *chip_name) | 2458 | const char *chip_name) |
| 2427 | { | 2459 | { |
| 2428 | struct amdgpu_device *adev = psp->adev; | 2460 | struct amdgpu_device *adev = psp->adev; |
| 2429 | char fw_name[30]; | 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 | const struct psp_firmware_header_v1_0 *sos_hdr; | 2498 | const struct psp_firmware_header_v1_0 *sos_hdr; |
| 2431 | const struct psp_firmware_header_v1_1 *sos_hdr_v1_1; | 2499 | const struct psp_firmware_header_v1_1 *sos_hdr_v1_1; |
| 2432 | const struct psp_firmware_header_v1_2 *sos_hdr_v1_2; | 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 | switch (desc->fw_type) { | 2589 | switch (desc->fw_type) { |
| 2522 | case TA_FW_TYPE_PSP_ASD: | 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 | psp->asd_feature_version = le32_to_cpu(desc->fw_version); | 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 | psp->asd_start_addr = ucode_start_addr; | 2594 | psp->asd_start_addr = ucode_start_addr; |
| 2595 | psp->asd_fw = psp->ta_fw; | ||
| 2527 | break; | 2596 | break; |
| 2528 | case TA_FW_TYPE_PSP_XGMI: | 2597 | case TA_FW_TYPE_PSP_XGMI: |
| 2529 | psp->ta_xgmi_ucode_version = le32_to_cpu(desc->fw_version); | 2598 | psp->ta_xgmi_ucode_version = le32_to_cpu(desc->fw_version); |
| @@ -41,6 +41,7 @@ · 40 unmodified lines | |||
| 41 | #define PSP_DTM_SHARED_MEM_SIZE 0x4000 | 41 | #define PSP_DTM_SHARED_MEM_SIZE 0x4000 |
| 42 | #define PSP_RAP_SHARED_MEM_SIZE 0x4000 | 42 | #define PSP_RAP_SHARED_MEM_SIZE 0x4000 |
| 43 | #define PSP_SHARED_MEM_SIZE 0x4000 | 43 | #define PSP_SHARED_MEM_SIZE 0x4000 |
| 44 | #define PSP_FW_NAME_LEN 0x24 | ||
| 44 | 45 | ||
| 45 | struct psp_context; | 46 | struct psp_context; |
| 46 | struct psp_xgmi_node_info; | 47 | struct psp_xgmi_node_info; |
| @@ -253,6 +254,11 @@ struct psp_context · 206 unmodified lines | |||
| 253 | uint32_t asd_ucode_size; | 254 | uint32_t asd_ucode_size; |
| 254 | uint8_t *asd_start_addr; | 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 | /* fence buffer */ | 262 | /* fence buffer */ |
| 257 | struct amdgpu_bo *fence_buf_bo; | 263 | struct amdgpu_bo *fence_buf_bo; |
| 258 | uint64_t fence_buf_mc_addr; | 264 | uint64_t fence_buf_mc_addr; |
| @@ -386,8 +392,12 @@ int psp_ring_cmd_submit(struct psp_context *psp, · 127 unmodified lines | |||
| 386 | int index); | 392 | int index); |
| 387 | int psp_init_asd_microcode(struct psp_context *psp, | 393 | int psp_init_asd_microcode(struct psp_context *psp, |
| 388 | const char *chip_name); | 394 | const char *chip_name); |
| 395 | int psp_init_toc_microcode(struct psp_context *psp, | ||
| 396 | const char *chip_name); | ||
| 389 | int psp_init_sos_microcode(struct psp_context *psp, | 397 | int psp_init_sos_microcode(struct psp_context *psp, |
| 390 | const char *chip_name); | 398 | const char *chip_name); |
| 391 | int psp_init_ta_microcode(struct psp_context *psp, | 399 | int psp_init_ta_microcode(struct psp_context *psp, |
| 392 | const char *chip_name); | 400 | const char *chip_name); |
| 401 | int psp_get_fw_attestation_records_addr(struct psp_context *psp, | ||
| 402 | uint64_t *output_ptr); | ||
| 393 | #endif | 403 | #endif |
| @@ -80,6 +80,8 @@ enum amdgpu_ras_retire_page_reservation { · 79 unmodified lines | |||
| 80 | 80 | ||
| 81 | atomic_t amdgpu_ras_in_intr = ATOMIC_INIT(0); | 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 | static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev, | 85 | static bool amdgpu_ras_check_bad_page(struct amdgpu_device *adev, |
| 84 | uint64_t addr); | 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 | /* obj end */ | 518 | /* obj end */ |
| 517 | 519 | ||
| 518 | static void amdgpu_ras_parse_status_code(struct amdgpu_device *adev, | 520 | static void amdgpu_ras_parse_status_code(struct amdgpu_device *adev, |
| 519 | const char* invoke_type, | 521 | const char* invoke_type, |
| 520 | const char* block_name, | 522 | const char* block_name, |
| 521 | enum ta_ras_status ret) | 523 | enum ta_ras_status ret) |
| 522 | { | 524 | { |
| 523 | switch (ret) { | 525 | switch (ret) { |
| 524 | case TA_RAS_STATUS__SUCCESS: | 526 | case TA_RAS_STATUS__SUCCESS: |
| @@ -607,7 +609,7 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev, · 82 unmodified lines | |||
| 607 | if (!con) | 609 | if (!con) |
| 608 | return -EINVAL; | 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 | if (!info) | 613 | if (!info) |
| 612 | return -ENOMEM; | 614 | return -ENOMEM; |
| 613 | 615 | ||
| @@ -953,7 +955,7 @@ static char *amdgpu_ras_badpage_flags_str(unsigned int flags) · 339 unmodified lines | |||
| 953 | case AMDGPU_RAS_RETIRE_PAGE_FAULT: | 955 | case AMDGPU_RAS_RETIRE_PAGE_FAULT: |
| 954 | default: | 956 | default: |
| 955 | return "F"; | 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 | .size = AMDGPU_GPU_PAGE_SIZE, | 1553 | .size = AMDGPU_GPU_PAGE_SIZE, |
| 1552 | .flags = AMDGPU_RAS_RETIRE_PAGE_RESERVED, | 1554 | .flags = AMDGPU_RAS_RETIRE_PAGE_RESERVED, |
| 1553 | }; | 1555 | }; |
| 1554 | 1556 | ret = amdgpu_vram_mgr_query_page_status( | |
| 1555 | if (data->last_reserved <= i) | 1557 | ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM), |
| 1558 | data->bps[i].retired_page); | ||
| 1559 | if (ret == -EBUSY) | ||
| 1556 | (*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_PENDING; | 1560 | (*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_PENDING; |
| 1557 | else if (data->bps_bo[i] == NULL) | 1561 | else if (ret == -ENOENT) |
| 1558 | (*bps)[i].flags = AMDGPU_RAS_RETIRE_PAGE_FAULT; | 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 | unsigned int new_space = old_space + pages; | 1610 | unsigned int new_space = old_space + pages; |
| 1607 | unsigned int align_space = ALIGN(new_space, 512); | 1611 | unsigned int align_space = ALIGN(new_space, 512); |
| 1608 | void *bps = kmalloc(align_space * sizeof(*data->bps), GFP_KERNEL); | 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 | kfree(bps); | 1615 | kfree(bps); |
| 1614 | kfree(bps_bo); | ||
| 1615 | return -ENOMEM; | 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 | data->count * sizeof(*data->bps)); | 1621 | data->count * sizeof(*data->bps)); |
| 1621 | kfree(data->bps); | 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 | data->bps = bps; | 1625 | data->bps = bps; |
| 1630 | data->bps_bo = bps_bo; | ||
| 1631 | data->space_left += align_space - old_space; | 1626 | data->space_left += align_space - old_space; |
| 1632 | return 0; | 1627 | return 0; |
| 1633 | } | 1628 | } |
| @@ -1639,6 +1634,7 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev, · 5 unmodified lines | |||
| 1639 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); | 1634 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); |
| 1640 | struct ras_err_handler_data *data; | 1635 | struct ras_err_handler_data *data; |
| 1641 | int ret = 0; | 1636 | int ret = 0; |
| 1637 | uint32_t i; | ||
| 1642 | 1638 | ||
| 1643 | if (!con || !con->eh_data || !bps || pages <= 0) | 1639 | if (!con || !con->eh_data || !bps || pages <= 0) |
| 1644 | return 0; | 1640 | return 0; |
| @@ -1648,16 +1644,26 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev, · 3 unmodified lines | |||
| 1648 | if (!data) | 1644 | if (!data) |
| 1649 | goto out; | 1645 | goto out; |
| 1650 | 1646 | ||
| 1651 | if (data->space_left <= pages) | 1647 | for (i = 0; i < pages; i++) { |
| 1652 | if (amdgpu_ras_realloc_eh_data_space(adev, data, pages)) { | 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 | ret = -ENOMEM; | 1654 | ret = -ENOMEM; |
| 1654 | goto out; | 1655 | goto out; |
| 1655 | } | 1656 | } |
| 1656 | 1657 | ||
| 1657 | memcpy(&data->bps[data->count], bps, pages * sizeof(*data->bps)); | 1658 | amdgpu_vram_mgr_reserve_range( |
| 1658 | data->count += pages; | 1659 | ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM), |
| 1659 | data->space_left -= pages; | 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 | out: | 1667 | out: |
| 1662 | mutex_unlock(&con->recovery_lock); | 1668 | mutex_unlock(&con->recovery_lock); |
| 1663 | 1669 | ||
| @@ -1668,7 +1674,7 @@ out: · 4 unmodified lines | |||
| 1668 | * write error record array to eeprom, the function should be | 1674 | * write error record array to eeprom, the function should be |
| 1669 | * protected by recovery_lock | 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 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); | 1679 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); |
| 1674 | struct ras_err_handler_data *data; | 1680 | struct ras_err_handler_data *data; |
| @@ -1730,6 +1736,20 @@ out: · 55 unmodified lines | |||
| 1730 | return ret; | 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 | * check if an address belongs to bad page | 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 | uint64_t addr) | 1759 | uint64_t addr) |
| 1740 | { | 1760 | { |
| 1741 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); | 1761 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); |
| 1742 | struct ras_err_handler_data *data; | ||
| 1743 | int i; | ||
| 1744 | bool ret = false; | 1762 | bool ret = false; |
| 1745 | 1763 | ||
| 1746 | if (!con || !con->eh_data) | 1764 | if (!con || !con->eh_data) |
| 1747 | return ret; | 1765 | return ret; |
| 1748 | 1766 | ||
| 1749 | mutex_lock(&con->recovery_lock); | 1767 | mutex_lock(&con->recovery_lock); |
| 1750 | data = con->eh_data; | 1768 | ret = amdgpu_ras_check_bad_page_unlock(con, addr); |
| 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: | ||
| 1762 | mutex_unlock(&con->recovery_lock); | 1769 | mutex_unlock(&con->recovery_lock); |
| 1763 | return ret; | 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 | int amdgpu_ras_recovery_init(struct amdgpu_device *adev) | 1814 | int amdgpu_ras_recovery_init(struct amdgpu_device *adev) |
| 1882 | { | 1815 | { |
| 1883 | struct amdgpu_ras *con = amdgpu_ras_get_context(adev); | 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 | ret = amdgpu_ras_load_bad_pages(adev); | 1850 | ret = amdgpu_ras_load_bad_pages(adev); |
| 1918 | if (ret) | 1851 | if (ret) |
| 1919 | goto free; | 1852 | goto free; |
| 1920 | ret = amdgpu_ras_reserve_bad_pages(adev); | ||
| 1921 | if (ret) | ||
| 1922 | goto release; | ||
| 1923 | } | 1853 | } |
| 1924 | 1854 | ||
| 1925 | return 0; | 1855 | return 0; |
| 1926 | 1856 | ||
| 1927 | release: | ||
| 1928 | amdgpu_ras_release_bad_pages(adev); | ||
| 1929 | free: | 1857 | free: |
| 1930 | kfree((*data)->bps); | 1858 | kfree((*data)->bps); |
| 1931 | kfree((*data)->bps_bo); | ||
| 1932 | kfree(*data); | 1859 | kfree(*data); |
| 1933 | con->eh_data = NULL; | 1860 | con->eh_data = NULL; |
| 1934 | out: | 1861 | out: |
| @@ -1956,12 +1883,10 @@ static int amdgpu_ras_recovery_fini(struct amdgpu_device *adev) · 21 unmodified lines | |||
| 1956 | return 0; | 1883 | return 0; |
| 1957 | 1884 | ||
| 1958 | cancel_work_sync(&con->recovery_work); | 1885 | cancel_work_sync(&con->recovery_work); |
| 1959 | amdgpu_ras_release_bad_pages(adev); | ||
| 1960 | 1886 | ||
| 1961 | mutex_lock(&con->recovery_lock); | 1887 | mutex_lock(&con->recovery_lock); |
| 1962 | con->eh_data = NULL; | 1888 | con->eh_data = NULL; |
| 1963 | kfree(data->bps); | 1889 | kfree(data->bps); |
| 1964 | kfree(data->bps_bo); | ||
| 1965 | kfree(data); | 1890 | kfree(data); |
| 1966 | mutex_unlock(&con->recovery_lock); | 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 | amdgpu_ras_sysfs_remove(adev, ras_block); | 2082 | amdgpu_ras_sysfs_remove(adev, ras_block); |
| 2158 | if (ih_info->cb) | 2083 | if (ih_info->cb) |
| 2159 | amdgpu_ras_interrupt_remove_handler(adev, ih_info); | 2084 | amdgpu_ras_interrupt_remove_handler(adev, ih_info); |
| 2160 | amdgpu_ras_feature_enable(adev, ras_block, 0); | 2085 | amdgpu_ras_feature_enable(adev, ras_block, 0); |
| 2161 | } | 2086 | } |
| 2162 | 2087 | ||
| @@ -33,7 +33,6 @@ · 32 unmodified lines | |||
| 33 | 33 | ||
| 34 | #define AMDGPU_RAS_FLAG_INIT_BY_VBIOS (0x1 << 0) | 34 | #define AMDGPU_RAS_FLAG_INIT_BY_VBIOS (0x1 << 0) |
| 35 | #define AMDGPU_RAS_FLAG_INIT_NEED_RESET (0x1 << 1) | 35 | #define AMDGPU_RAS_FLAG_INIT_NEED_RESET (0x1 << 1) |
| 36 | #define AMDGPU_RAS_FLAG_SKIP_BAD_PAGE_RESV (0x1 << 2) | ||
| 37 | 36 | ||
| 38 | enum amdgpu_ras_block { | 37 | enum amdgpu_ras_block { |
| 39 | AMDGPU_RAS_BLOCK__UMC = 0, | 38 | AMDGPU_RAS_BLOCK__UMC = 0, |
| @@ -363,14 +362,10 @@ struct ras_err_data { · 323 unmodified lines | |||
| 363 | struct ras_err_handler_data { | 362 | struct ras_err_handler_data { |
| 364 | /* point to bad page records array */ | 363 | /* point to bad page records array */ |
| 365 | struct eeprom_table_record *bps; | 364 | struct eeprom_table_record *bps; |
| 366 | /* point to reserved bo array */ | ||
| 367 | struct amdgpu_bo **bps_bo; | ||
| 368 | /* the count of entries */ | 365 | /* the count of entries */ |
| 369 | int count; | 366 | int count; |
| 370 | /* the space can place new entries */ | 367 | /* the space can place new entries */ |
| 371 | int space_left; | 368 | int space_left; |
| 372 | /* last reserved entry's index + 1 */ | ||
| 373 | int last_reserved; | ||
| 374 | }; | 369 | }; |
| 375 | 370 | ||
| 376 | typedef int (*ras_ih_cb)(struct amdgpu_device *adev, | 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 | int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev, | 501 | int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev, |
| 507 | struct eeprom_table_record *bps, int pages); | 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 | static inline int amdgpu_ras_reset_gpu(struct amdgpu_device *adev) | 506 | static inline int amdgpu_ras_reset_gpu(struct amdgpu_device *adev) |
| 512 | { | 507 | { |
| 513 | struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); | 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 | if (atomic_cmpxchg(&ras->in_recovery, 0, 1) == 0) | 510 | if (atomic_cmpxchg(&ras->in_recovery, 0, 1) == 0) |
| 526 | schedule_work(&ras->recovery_work); | 511 | schedule_work(&ras->recovery_work); |
| 527 | return 0; | 512 | return 0; |
| @@ -27,9 +27,9 @@ · 26 unmodified lines | |||
| 27 | #include <linux/bits.h> | 27 | #include <linux/bits.h> |
| 28 | #include "atom.h" | 28 | #include "atom.h" |
| 29 | 29 | ||
| 30 | #define EEPROM_I2C_TARGET_ADDR_VEGA20 0xA0 | 30 | #define EEPROM_I2C_TARGET_ADDR_VEGA20 0xA0 |
| 31 | #define EEPROM_I2C_TARGET_ADDR_ARCTURUS 0xA8 | 31 | #define EEPROM_I2C_TARGET_ADDR_ARCTURUS 0xA8 |
| 32 | #define EEPROM_I2C_TARGET_ADDR_ARCTURUS_D342 0xA0 | 32 | #define EEPROM_I2C_TARGET_ADDR_ARCTURUS_D342 0xA0 |
| 33 | 33 | ||
| 34 | /* | 34 | /* |
| 35 | * The 2 macros bellow represent the actual size in bytes that | 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 | uint32_t *pp = (uint32_t *)buff; | 125 | uint32_t *pp = (uint32_t *)buff; |
| 126 | 126 | ||
| 127 | hdr->header = le32_to_cpu(pp[0]); | 127 | hdr->header = le32_to_cpu(pp[0]); |
| 128 | hdr->version = le32_to_cpu(pp[1]); | 128 | hdr->version = le32_to_cpu(pp[1]); |
| 129 | hdr->first_rec_offset = le32_to_cpu(pp[2]); | 129 | hdr->first_rec_offset = le32_to_cpu(pp[2]); |
| 130 | hdr->tbl_size = le32_to_cpu(pp[3]); | 130 | hdr->tbl_size = le32_to_cpu(pp[3]); |
| 131 | hdr->checksum = le32_to_cpu(pp[4]); | 131 | hdr->checksum = le32_to_cpu(pp[4]); |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | static int __update_table_header(struct amdgpu_ras_eeprom_control *control, | 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 | msg.addr = control->i2c_address; | 150 | msg.addr = control->i2c_address; |
| 151 | 151 | ||
| 152 | /* i2c may be unstable in gpu reset */ | ||
| 153 | down_read(&adev->reset_sem); | ||
| 152 | ret = i2c_transfer(&adev->pm.smu_i2c, &msg, 1); | 154 | ret = i2c_transfer(&adev->pm.smu_i2c, &msg, 1); |
| 155 | up_read(&adev->reset_sem); | ||
| 156 | |||
| 153 | if (ret < 1) | 157 | if (ret < 1) |
| 154 | DRM_ERROR("Failed to write EEPROM table header, ret:%d", ret); | 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 | int i, ret = 0; | 479 | int i, ret = 0; |
| 476 | struct i2c_msg *msgs, *msg; | 480 | struct i2c_msg *msgs, *msg; |
| 477 | unsigned char *buffs, *buff; | 481 | unsigned char *buffs, *buff; |
| 478 | bool sched_ras_recovery = false; | ||
| 479 | struct eeprom_table_record *record; | 482 | struct eeprom_table_record *record; |
| 480 | struct amdgpu_device *adev = to_amdgpu_device(control); | 483 | struct amdgpu_device *adev = to_amdgpu_device(control); |
| 481 | struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); | 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 | "Saved bad pages(%d) reaches threshold value(%d).\n", | 516 | "Saved bad pages(%d) reaches threshold value(%d).\n", |
| 514 | control->num_recs + num, ras->bad_page_cnt_threshold); | 517 | control->num_recs + num, ras->bad_page_cnt_threshold); |
| 515 | control->tbl_hdr.header = EEPROM_TABLE_HDR_BAD; | 518 | control->tbl_hdr.header = EEPROM_TABLE_HDR_BAD; |
| 516 | sched_ras_recovery = true; | ||
| 517 | } | 519 | } |
| 518 | 520 | ||
| 519 | /* In case of overflow just start from beginning to not lose newest records */ | 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 | control->next_addr += EEPROM_TABLE_RECORD_SIZE; | 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 | ret = i2c_transfer(&adev->pm.smu_i2c, msgs, num); | 564 | ret = i2c_transfer(&adev->pm.smu_i2c, msgs, num); |
| 565 | up_read(&adev->reset_sem); | ||
| 566 | |||
| 561 | if (ret < 1) { | 567 | if (ret < 1) { |
| 562 | DRM_ERROR("Failed to process EEPROM table records, ret:%d", ret); | 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 | __update_tbl_checksum(control, records, num, old_hdr_byte_sum); | 601 | __update_tbl_checksum(control, records, num, old_hdr_byte_sum); |
| 596 | 602 | ||
| 597 | __update_table_header(control, buffs); | 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 | } else if (!__validate_tbl_checksum(control, records, num)) { | 604 | } else if (!__validate_tbl_checksum(control, records, num)) { |
| 613 | DRM_WARN("EEPROM Table checksum mismatch!"); | 605 | DRM_WARN("EEPROM Table checksum mismatch!"); |
| 614 | /* TODO Uncomment when EEPROM read/write is relliable */ | 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 | return result; | 396 | return result; |
| 397 | 397 | ||
| 398 | value = ring->ring[(*pos - 12)/4]; | 398 | value = ring->ring[(*pos - 12)/4]; |
| 399 | r = put_user(value, (uint32_t*)buf); | 399 | r = put_user(value, (uint32_t *)buf); |
| 400 | if (r) | 400 | if (r) |
| 401 | return r; | 401 | return r; |
| 402 | buf += 4; | 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 | void amdgpu_sa_bo_manager_fini(struct amdgpu_device *adev, | 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 | struct amdgpu_sa_bo *sa_bo, *tmp; | 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 | goto free; | 126 | goto free; |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | return 0; | 129 | return 0; |
| 130 | 130 | ||
| 131 | late_fini: | 131 | late_fini: |
| 132 | amdgpu_ras_late_fini(adev, adev->sdma.ras_if, ih_info); | 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 | i, *vram_start, gart_start, | 157 | i, *vram_start, gart_start, |
| 158 | (unsigned long long) | 158 | (unsigned long long) |
| 159 | (gart_addr - adev->gmc.gart_start + | 159 | (gart_addr - adev->gmc.gart_start + |
| 160 | (void*)gart_start - gtt_map), | 160 | (void *)gart_start - gtt_map), |
| 161 | (unsigned long long) | 161 | (unsigned long long) |
| 162 | (vram_addr - adev->gmc.vram_start + | 162 | (vram_addr - adev->gmc.vram_start + |
| 163 | (void*)gart_start - gtt_map)); | 163 | (void *)gart_start - gtt_map)); |
| 164 | amdgpu_bo_kunmap(vram_obj); | 164 | amdgpu_bo_kunmap(vram_obj); |
| 165 | goto out_lclean_unpin; | 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 | i, *gart_start, vram_start, | 203 | i, *gart_start, vram_start, |
| 204 | (unsigned long long) | 204 | (unsigned long long) |
| 205 | (vram_addr - adev->gmc.vram_start + | 205 | (vram_addr - adev->gmc.vram_start + |
| 206 | (void*)vram_start - vram_map), | 206 | (void *)vram_start - vram_map), |
| 207 | (unsigned long long) | 207 | (unsigned long long) |
| 208 | (gart_addr - adev->gmc.gart_start + | 208 | (gart_addr - adev->gmc.gart_start + |
| 209 | (void*)vram_start - vram_map)); | 209 | (void *)vram_start - vram_map)); |
| 210 | amdgpu_bo_kunmap(gtt_obj[i]); | 210 | amdgpu_bo_kunmap(gtt_obj[i]); |
| 211 | goto out_lclean_unpin; | 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 | static int amdgpu_ttm_init_on_chip(struct amdgpu_device *adev, | 71 | static int amdgpu_ttm_init_on_chip(struct amdgpu_device *adev, |
| 72 | unsigned int type, | 72 | unsigned int type, |
| 73 | uint64_t size) | 73 | uint64_t size_in_page) |
| 74 | { | 74 | { |
| 75 | return ttm_range_man_init(&adev->mman.bdev, type, | 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 | * Called by amdgpu_ttm_backend_bind() | 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 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); | 1199 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); |
| 1200 | struct ttm_operation_ctx ctx = { false, false }; | 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 | struct ttm_resource tmp; | 1202 | struct ttm_resource tmp; |
| 1203 | struct ttm_placement placement; | 1203 | struct ttm_placement placement; |
| 1204 | struct ttm_place placements; | 1204 | struct ttm_place placements; |
| @@ -1449,7 +1449,7 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_buffer_object *bo, · 244 unmodified lines | |||
| 1449 | return -ENOMEM; | 1449 | return -ENOMEM; |
| 1450 | } | 1450 | } |
| 1451 | 1451 | ||
| 1452 | gtt = (void*)bo->ttm; | 1452 | gtt = (void *)bo->ttm; |
| 1453 | gtt->userptr = addr; | 1453 | gtt->userptr = addr; |
| 1454 | gtt->userflags = flags; | 1454 | gtt->userflags = flags; |
| 1455 | 1455 | ||
| @@ -37,10 +37,17 @@ · 36 unmodified lines | |||
| 37 | 37 | ||
| 38 | #define AMDGPU_POISON 0xd0bed0be | 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 | struct amdgpu_vram_mgr { | 45 | struct amdgpu_vram_mgr { |
| 41 | struct ttm_resource_manager manager; | 46 | struct ttm_resource_manager manager; |
| 42 | struct drm_mm mm; | 47 | struct drm_mm mm; |
| 43 | spinlock_t lock; | 48 | spinlock_t lock; |
| 49 | struct list_head reservations_pending; | ||
| 50 | struct list_head reserved_pages; | ||
| 44 | atomic64_t usage; | 51 | atomic64_t usage; |
| 45 | atomic64_t vis_usage; | 52 | atomic64_t vis_usage; |
| 46 | }; | 53 | }; |
| @@ -54,7 +61,6 @@ struct amdgpu_gtt_mgr { · 7 unmodified lines | |||
| 54 | 61 | ||
| 55 | struct amdgpu_mman { | 62 | struct amdgpu_mman { |
| 56 | struct ttm_bo_device bdev; | 63 | struct ttm_bo_device bdev; |
| 57 | bool mem_global_referenced; | ||
| 58 | bool initialized; | 64 | bool initialized; |
| 59 | void __iomem *aper_base_kaddr; | 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 | struct sg_table *sgt); | 125 | struct sg_table *sgt); |
| 120 | uint64_t amdgpu_vram_mgr_usage(struct ttm_resource_manager *man); | 126 | uint64_t amdgpu_vram_mgr_usage(struct ttm_resource_manager *man); |
| 121 | uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_resource_manager *man); | 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 | int amdgpu_ttm_init(struct amdgpu_device *adev); | 133 | int amdgpu_ttm_init(struct amdgpu_device *adev); |
| 124 | void amdgpu_ttm_late_init(struct amdgpu_device *adev); | 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 | case CHIP_NAVI12: | 391 | case CHIP_NAVI12: |
| 392 | case CHIP_SIENNA_CICHLID: | 392 | case CHIP_SIENNA_CICHLID: |
| 393 | case CHIP_NAVY_FLOUNDER: | 393 | case CHIP_NAVY_FLOUNDER: |
| 394 | case CHIP_VANGOGH: | ||
| 395 | case CHIP_DIMGREY_CAVEFISH: | ||
| 394 | if (!load_type) | 396 | if (!load_type) |
| 395 | return AMDGPU_FW_LOAD_DIRECT; | 397 | return AMDGPU_FW_LOAD_DIRECT; |
| 396 | else | 398 | else |
| @@ -586,8 +588,8 @@ static int amdgpu_ucode_patch_jt(struct amdgpu_firmware_info *ucode, · 189 unmodified lines | |||
| 586 | { | 588 | { |
| 587 | const struct gfx_firmware_header_v1_0 *header = NULL; | 589 | const struct gfx_firmware_header_v1_0 *header = NULL; |
| 588 | const struct common_firmware_header *comm_hdr = NULL; | 590 | const struct common_firmware_header *comm_hdr = NULL; |
| 589 | uint8_t* src_addr = NULL; | 591 | uint8_t *src_addr = NULL; |
| 590 | uint8_t* dst_addr = NULL; | 592 | uint8_t *dst_addr = NULL; |
| 591 | 593 | ||
| 592 | if (NULL == ucode->fw) | 594 | if (NULL == ucode->fw) |
| 593 | return 0; | 595 | return 0; |
| @@ -126,10 +126,11 @@ int amdgpu_umc_process_ras_data_cb(struct amdgpu_device *adev, · 125 unmodified lines | |||
| 126 | err_data->ue_count); | 126 | err_data->ue_count); |
| 127 | 127 | ||
| 128 | if ((amdgpu_bad_page_threshold != 0) && | 128 | if ((amdgpu_bad_page_threshold != 0) && |
| 129 | err_data->err_addr_cnt && | 129 | err_data->err_addr_cnt) { |
| 130 | amdgpu_ras_add_bad_pages(adev, err_data->err_addr, | 130 | amdgpu_ras_add_bad_pages(adev, err_data->err_addr, |
| 131 | err_data->err_addr_cnt)) | 131 | err_data->err_addr_cnt); |
| 132 | dev_warn(adev->dev, "Failed to add ras bad page!\n"); | 132 | amdgpu_ras_save_bad_pages(adev); |
| 133 | } | ||
| 133 | 134 | ||
| 134 | amdgpu_ras_reset_gpu(adev); | 135 | amdgpu_ras_reset_gpu(adev); |
| 135 | } | 136 | } |
| @@ -37,24 +37,30 @@ · 36 unmodified lines | |||
| 37 | #define FIRMWARE_RAVEN "amdgpu/raven_vcn.bin" | 37 | #define FIRMWARE_RAVEN "amdgpu/raven_vcn.bin" |
| 38 | #define FIRMWARE_PICASSO "amdgpu/picasso_vcn.bin" | 38 | #define FIRMWARE_PICASSO "amdgpu/picasso_vcn.bin" |
| 39 | #define FIRMWARE_RAVEN2 "amdgpu/raven2_vcn.bin" | 39 | #define FIRMWARE_RAVEN2 "amdgpu/raven2_vcn.bin" |
| 40 | #define FIRMWARE_ARCTURUS "amdgpu/arcturus_vcn.bin" | 40 | #define FIRMWARE_ARCTURUS "amdgpu/arcturus_vcn.bin" |
| 41 | #define FIRMWARE_RENOIR "amdgpu/renoir_vcn.bin" | 41 | #define FIRMWARE_RENOIR "amdgpu/renoir_vcn.bin" |
| 42 | #define FIRMWARE_NAVI10 "amdgpu/navi10_vcn.bin" | 42 | #define FIRMWARE_GREEN_SARDINE "amdgpu/green_sardine_vcn.bin" |
| 43 | #define FIRMWARE_NAVI14 "amdgpu/navi14_vcn.bin" | 43 | #define FIRMWARE_NAVI10 "amdgpu/navi10_vcn.bin" |
| 44 | #define FIRMWARE_NAVI12 "amdgpu/navi12_vcn.bin" | 44 | #define FIRMWARE_NAVI14 "amdgpu/navi14_vcn.bin" |
| 45 | #define FIRMWARE_SIENNA_CICHLID "amdgpu/sienna_cichlid_vcn.bin" | 45 | #define FIRMWARE_NAVI12 "amdgpu/navi12_vcn.bin" |
| 46 | #define FIRMWARE_NAVY_FLOUNDER "amdgpu/navy_flounder_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 | MODULE_FIRMWARE(FIRMWARE_RAVEN); | 51 | MODULE_FIRMWARE(FIRMWARE_RAVEN); |
| 49 | MODULE_FIRMWARE(FIRMWARE_PICASSO); | 52 | MODULE_FIRMWARE(FIRMWARE_PICASSO); |
| 50 | MODULE_FIRMWARE(FIRMWARE_RAVEN2); | 53 | MODULE_FIRMWARE(FIRMWARE_RAVEN2); |
| 51 | MODULE_FIRMWARE(FIRMWARE_ARCTURUS); | 54 | MODULE_FIRMWARE(FIRMWARE_ARCTURUS); |
| 52 | MODULE_FIRMWARE(FIRMWARE_RENOIR); | 55 | MODULE_FIRMWARE(FIRMWARE_RENOIR); |
| 56 | MODULE_FIRMWARE(FIRMWARE_GREEN_SARDINE); | ||
| 53 | MODULE_FIRMWARE(FIRMWARE_NAVI10); | 57 | MODULE_FIRMWARE(FIRMWARE_NAVI10); |
| 54 | MODULE_FIRMWARE(FIRMWARE_NAVI14); | 58 | MODULE_FIRMWARE(FIRMWARE_NAVI14); |
| 55 | MODULE_FIRMWARE(FIRMWARE_NAVI12); | 59 | MODULE_FIRMWARE(FIRMWARE_NAVI12); |
| 56 | MODULE_FIRMWARE(FIRMWARE_SIENNA_CICHLID); | 60 | MODULE_FIRMWARE(FIRMWARE_SIENNA_CICHLID); |
| 57 | MODULE_FIRMWARE(FIRMWARE_NAVY_FLOUNDER); | 61 | MODULE_FIRMWARE(FIRMWARE_NAVY_FLOUNDER); |
| 62 | MODULE_FIRMWARE(FIRMWARE_VANGOGH); | ||
| 63 | MODULE_FIRMWARE(FIRMWARE_DIMGREY_CAVEFISH); | ||
| 58 | 64 | ||
| 59 | static void amdgpu_vcn_idle_work_handler(struct work_struct *work); | 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 | adev->vcn.indirect_sram = true; | 95 | adev->vcn.indirect_sram = true; |
| 90 | break; | 96 | break; |
| 91 | case CHIP_RENOIR: | 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 | if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && | 103 | if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && |
| 94 | (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) | 104 | (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) |
| 95 | adev->vcn.indirect_sram = true; | 105 | adev->vcn.indirect_sram = true; |
| @@ -124,6 +134,15 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev) · 28 unmodified lines | |||
| 124 | (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) | 134 | (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) |
| 125 | adev->vcn.indirect_sram = true; | 135 | adev->vcn.indirect_sram = true; |
| 126 | break; | 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 | default: | 146 | default: |
| 128 | return -EINVAL; | 147 | return -EINVAL; |
| 129 | } | 148 | } |
| @@ -313,6 +332,7 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work) · 183 unmodified lines | |||
| 313 | container_of(work, struct amdgpu_device, vcn.idle_work.work); | 332 | container_of(work, struct amdgpu_device, vcn.idle_work.work); |
| 314 | unsigned int fences = 0, fence[AMDGPU_MAX_VCN_INSTANCES] = {0}; | 333 | unsigned int fences = 0, fence[AMDGPU_MAX_VCN_INSTANCES] = {0}; |
| 315 | unsigned int i, j; | 334 | unsigned int i, j; |
| 335 | int r = 0; | ||
| 316 | 336 | ||
| 317 | for (j = 0; j < adev->vcn.num_vcn_inst; ++j) { | 337 | for (j = 0; j < adev->vcn.num_vcn_inst; ++j) { |
| 318 | if (adev->vcn.harvest_config & (1 << j)) | 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 | if (!fences && !atomic_read(&adev->vcn.total_submission_cnt)) { | 361 | if (!fences && !atomic_read(&adev->vcn.total_submission_cnt)) { |
| 362 | amdgpu_gfx_off_ctrl(adev, true); | ||
| 342 | amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, | 363 | amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, |
| 343 | AMD_PG_STATE_GATE); | 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 | } else { | 369 | } else { |
| 345 | schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT); | 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 | void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring) | 374 | void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring) |
| 350 | { | 375 | { |
| 351 | struct amdgpu_device *adev = ring->adev; | 376 | struct amdgpu_device *adev = ring->adev; |
| 377 | int r = 0; | ||
| 352 | 378 | ||
| 353 | atomic_inc(&adev->vcn.total_submission_cnt); | 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 | mutex_lock(&adev->vcn.vcn_pg_lock); | 389 | mutex_lock(&adev->vcn.vcn_pg_lock); |
| 357 | amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN, | 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 | return; | 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 | AMDGPU_FW_VRAM_PF2VF_READ (adev, feature_flags, &pf2vf_flags); | 63 | AMDGPU_FW_VRAM_PF2VF_READ (adev, feature_flags, &pf2vf_flags); |
| 64 | if (!(pf2vf_flags & AMDGIM_FEATURE_ERROR_LOG_COLLECT)) { | 64 | if (!(pf2vf_flags & AMDGIM_FEATURE_ERROR_LOG_COLLECT)) { |
| 65 | return; | 65 | return; |
| @@ -300,7 +300,7 @@ static void amdgpu_vm_bo_relocated(struct amdgpu_vm_bo_base *vm_bo) · 299 unmodified lines | |||
| 300 | static void amdgpu_vm_bo_done(struct amdgpu_vm_bo_base *vm_bo) | 300 | static void amdgpu_vm_bo_done(struct amdgpu_vm_bo_base *vm_bo) |
| 301 | { | 301 | { |
| 302 | spin_lock(&vm_bo->vm->invalidated_lock); | 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 | spin_unlock(&vm_bo->vm->invalidated_lock); | 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 | * amdgpu_vm_bo_update_mapping - update a mapping in the vm page table | 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 | * @vm: requested vm | 1575 | * @vm: requested vm |
| 1575 | * @immediate: immediate submission in a page fault | 1576 | * @immediate: immediate submission in a page fault |
| 1576 | * @unlocked: unlocked invalidation during MM callback | 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 | * @start: start of mapped range | 1579 | * @start: start of mapped range |
| 1579 | * @last: last mapped entry | 1580 | * @last: last mapped entry |
| 1580 | * @flags: flags for the entries | 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 | * @pages_addr: DMA addresses to use for mapping | 1584 | * @pages_addr: DMA addresses to use for mapping |
| 1583 | * @fence: optional resulting fence | 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 | * 0 for success, -EINVAL for failure. | 1590 | * 0 for success, -EINVAL for failure. |
| 1589 | */ | 1591 | */ |
| 1590 | static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | 1592 | static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, |
| 1593 | struct amdgpu_device *bo_adev, | ||
| 1591 | struct amdgpu_vm *vm, bool immediate, | 1594 | struct amdgpu_vm *vm, bool immediate, |
| 1592 | bool unlocked, struct dma_resv *resv, | 1595 | bool unlocked, struct dma_resv *resv, |
| 1593 | uint64_t start, uint64_t last, | 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 | dma_addr_t *pages_addr, | 1599 | dma_addr_t *pages_addr, |
| 1596 | struct dma_fence **fence) | 1600 | struct dma_fence **fence) |
| 1597 | { | 1601 | { |
| 1598 | struct amdgpu_vm_update_params params; | 1602 | struct amdgpu_vm_update_params params; |
| 1599 | enum amdgpu_sync_mode sync_mode; | 1603 | enum amdgpu_sync_mode sync_mode; |
| 1604 | uint64_t pfn; | ||
| 1600 | int r; | 1605 | int r; |
| 1601 | 1606 | ||
| 1602 | memset(¶ms, 0, sizeof(params)); | 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 | else | 1619 | else |
| 1615 | sync_mode = AMDGPU_SYNC_EXPLICIT; | 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 | amdgpu_vm_eviction_lock(vm); | 1630 | amdgpu_vm_eviction_lock(vm); |
| 1618 | if (vm->evicting) { | 1631 | if (vm->evicting) { |
| 1619 | r = -EBUSY; | 1632 | r = -EBUSY; |
| @@ -1632,105 +1645,47 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, · 12 unmodified lines | |||
| 1632 | if (r) | 1645 | if (r) |
| 1633 | goto error_unlock; | 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 | do { | 1648 | do { |
| 1701 | dma_addr_t *dma_addr = NULL; | 1649 | uint64_t tmp, num_entries, addr; |
| 1702 | uint64_t max_entries; | 1650 | |
| 1703 | uint64_t addr, last; | ||
| 1704 | 1651 | ||
| 1705 | max_entries = mapping->last - start + 1; | 1652 | num_entries = last - start + 1; |
| 1706 | if (nodes) { | 1653 | if (nodes) { |
| 1707 | addr = nodes->start << PAGE_SHIFT; | 1654 | addr = nodes->start << PAGE_SHIFT; |
| 1708 | max_entries = min((nodes->size - pfn) * | 1655 | num_entries = min((nodes->size - pfn) * |
| 1709 | AMDGPU_GPU_PAGES_IN_CPU_PAGE, max_entries); | 1656 | AMDGPU_GPU_PAGES_IN_CPU_PAGE, num_entries); |
| 1710 | } else { | 1657 | } else { |
| 1711 | addr = 0; | 1658 | addr = 0; |
| 1712 | } | 1659 | } |
| 1713 | 1660 | ||
| 1714 | if (pages_addr) { | 1661 | if (pages_addr) { |
| 1715 | uint64_t count; | 1662 | bool contiguous = true; |
| 1716 | 1663 | ||
| 1717 | for (count = 1; | 1664 | if (num_entries > AMDGPU_GPU_PAGES_IN_CPU_PAGE) { |
| 1718 | count < max_entries / AMDGPU_GPU_PAGES_IN_CPU_PAGE; | 1665 | uint64_t count; |
| 1719 | ++count) { | ||
| 1720 | uint64_t idx = pfn + count; | ||
| 1721 | 1666 | ||
| 1722 | if (pages_addr[idx] != | 1667 | contiguous = pages_addr[pfn + 1] == |
| 1723 | (pages_addr[idx - 1] + PAGE_SIZE)) | 1668 | pages_addr[pfn] + PAGE_SIZE; |
| 1724 | break; | 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 | addr = pfn << PAGE_SHIFT; | 1684 | addr = pfn << PAGE_SHIFT; |
| 1729 | dma_addr = pages_addr; | 1685 | params.pages_addr = pages_addr; |
| 1730 | } else { | 1686 | } else { |
| 1731 | addr = pages_addr[pfn]; | 1687 | addr = pages_addr[pfn]; |
| 1732 | max_entries = count * | 1688 | params.pages_addr = NULL; |
| 1733 | AMDGPU_GPU_PAGES_IN_CPU_PAGE; | ||
| 1734 | } | 1689 | } |
| 1735 | 1690 | ||
| 1736 | } else if (flags & (AMDGPU_PTE_VALID | AMDGPU_PTE_PRT)) { | 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 | addr += pfn << PAGE_SHIFT; | 1693 | addr += pfn << PAGE_SHIFT; |
| 1739 | } | 1694 | } |
| 1740 | 1695 | ||
| 1741 | last = start + max_entries - 1; | 1696 | tmp = start + num_entries; |
| 1742 | r = amdgpu_vm_bo_update_mapping(adev, vm, false, false, resv, | 1697 | r = amdgpu_vm_update_ptes(¶ms, start, tmp, addr, flags); |
| 1743 | start, last, flags, addr, | ||
| 1744 | dma_addr, fence); | ||
| 1745 | if (r) | 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 | if (nodes && nodes->size == pfn) { | 1702 | if (nodes && nodes->size == pfn) { |
| 1750 | pfn = 0; | 1703 | pfn = 0; |
| 1751 | ++nodes; | 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 | list_for_each_entry(mapping, &bo_va->invalids, list) { | 1791 | list_for_each_entry(mapping, &bo_va->invalids, list) { |
| 1835 | r = amdgpu_vm_bo_split_mapping(adev, resv, pages_addr, vm, | 1792 | uint64_t update_flags = flags; |
| 1836 | mapping, flags, bo_adev, nodes, | 1793 | |
| 1837 | last_update); | 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 | if (r) | 1812 | if (r) |
| 1839 | return r; | 1813 | return r; |
| 1840 | } | 1814 | } |
| @@ -2042,9 +2016,10 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, · 201 unmodified lines | |||
| 2042 | mapping->start < AMDGPU_GMC_HOLE_START) | 2016 | mapping->start < AMDGPU_GMC_HOLE_START) |
| 2043 | init_pte_value = AMDGPU_PTE_DEFAULT_ATC; | 2017 | init_pte_value = AMDGPU_PTE_DEFAULT_ATC; |
| 2044 | 2018 | ||
| 2045 | r = amdgpu_vm_bo_update_mapping(adev, vm, false, false, resv, | 2019 | r = amdgpu_vm_bo_update_mapping(adev, adev, vm, false, false, |
| 2046 | mapping->start, mapping->last, | 2020 | resv, mapping->start, |
| 2047 | init_pte_value, 0, NULL, &f); | 2021 | mapping->last, init_pte_value, |
| 2022 | 0, NULL, NULL, &f); | ||
| 2048 | amdgpu_vm_free_mapping(adev, vm, mapping, f); | 2023 | amdgpu_vm_free_mapping(adev, vm, mapping, f); |
| 2049 | if (r) { | 2024 | if (r) { |
| 2050 | dma_fence_put(f); | 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 | * @adev: amdgpu_device pointer | 2143 | * @adev: amdgpu_device pointer |
| 2169 | * @bo_va: bo_va to store the address | 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 | INIT_LIST_HEAD(&vm->invalidated); | 2795 | INIT_LIST_HEAD(&vm->invalidated); |
| 2821 | spin_lock_init(&vm->invalidated_lock); | 2796 | spin_lock_init(&vm->invalidated_lock); |
| 2822 | INIT_LIST_HEAD(&vm->freed); | 2797 | INIT_LIST_HEAD(&vm->freed); |
| 2823 | 2798 | INIT_LIST_HEAD(&vm->done); | |
| 2824 | 2799 | ||
| 2825 | /* create scheduler entities for page table updates */ | 2800 | /* create scheduler entities for page table updates */ |
| 2826 | r = drm_sched_entity_init(&vm->immediate, DRM_SCHED_PRIORITY_NORMAL, | 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 | value = 0; | 3347 | value = 0; |
| 3373 | } | 3348 | } |
| 3374 | 3349 | ||
| 3375 | r = amdgpu_vm_bo_update_mapping(adev, vm, true, false, NULL, addr, | 3350 | r = amdgpu_vm_bo_update_mapping(adev, adev, vm, true, false, NULL, addr, |
| 3376 | addr + 1, flags, value, NULL, NULL); | 3351 | addr, flags, value, NULL, NULL, |
| 3352 | NULL); | ||
| 3377 | if (r) | 3353 | if (r) |
| 3378 | goto error_unlock; | 3354 | goto error_unlock; |
| 3379 | 3355 | ||
| @@ -3389,3 +3365,99 @@ error_unref: · 9 unmodified lines | |||
| 3389 | 3365 | ||
| 3390 | return false; | 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 | /* PTE is handled as PDE for VEGA10 (Translate Further) */ | 76 | /* PTE is handled as PDE for VEGA10 (Translate Further) */ |
| 77 | #define AMDGPU_PTE_TF (1ULL << 56) | 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 | /* PDE Block Fragment Size for VEGA10 */ | 82 | /* PDE Block Fragment Size for VEGA10 */ |
| 80 | #define AMDGPU_PDE_BFS(a) ((uint64_t)a << 59) | 83 | #define AMDGPU_PDE_BFS(a) ((uint64_t)a << 59) |
| 81 | 84 | ||
| @@ -274,6 +277,9 @@ struct amdgpu_vm { · 192 unmodified lines | |||
| 274 | /* BO mappings freed, but not yet updated in the PT */ | 277 | /* BO mappings freed, but not yet updated in the PT */ |
| 275 | struct list_head freed; | 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 | /* contains the page directory */ | 283 | /* contains the page directory */ |
| 278 | struct amdgpu_vm_pt root; | 284 | struct amdgpu_vm_pt root; |
| 279 | struct dma_fence *last_update; | 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 | struct amdgpu_vm *vm); | 447 | struct amdgpu_vm *vm); |
| 442 | void amdgpu_vm_del_from_lru_notify(struct ttm_buffer_object *bo); | 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 | #endif | 454 | #endif |
| @@ -168,8 +168,7 @@ static const struct ttm_resource_manager_func amdgpu_vram_mgr_func; · 167 unmodified lines | |||
| 168 | /** | 168 | /** |
| 169 | * amdgpu_vram_mgr_init - init VRAM manager and DRM MM | 169 | * amdgpu_vram_mgr_init - init VRAM manager and DRM MM |
| 170 | * | 170 | * |
| 171 | * @man: TTM memory type manager | 171 | * @adev: amdgpu_device pointer |
| 172 | * @p_size: maximum size of VRAM | ||
| 173 | * | 172 | * |
| 174 | * Allocate and initialize the VRAM manager. | 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 | drm_mm_init(&mgr->mm, 0, man->size); | 185 | drm_mm_init(&mgr->mm, 0, man->size); |
| 187 | spin_lock_init(&mgr->lock); | 186 | spin_lock_init(&mgr->lock); |
| 187 | INIT_LIST_HEAD(&mgr->reservations_pending); | ||
| 188 | INIT_LIST_HEAD(&mgr->reserved_pages); | ||
| 188 | 189 | ||
| 189 | /* Add the two VRAM-related sysfs files */ | 190 | /* Add the two VRAM-related sysfs files */ |
| 190 | ret = sysfs_create_files(&adev->dev->kobj, amdgpu_vram_mgr_attributes); | 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 | * amdgpu_vram_mgr_fini - free and destroy VRAM manager | 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 | * Destroy and free the VRAM manager, returns -EBUSY if ranges are still | 205 | * Destroy and free the VRAM manager, returns -EBUSY if ranges are still |
| 205 | * allocated inside it. | 206 | * allocated inside it. |
| @@ -209,6 +210,7 @@ void amdgpu_vram_mgr_fini(struct amdgpu_device *adev) · 3 unmodified lines | |||
| 209 | struct amdgpu_vram_mgr *mgr = &adev->mman.vram_mgr; | 210 | struct amdgpu_vram_mgr *mgr = &adev->mman.vram_mgr; |
| 210 | struct ttm_resource_manager *man = &mgr->manager; | 211 | struct ttm_resource_manager *man = &mgr->manager; |
| 211 | int ret; | 212 | int ret; |
| 213 | struct amdgpu_vram_reservation *rsv, *temp; | ||
| 212 | 214 | ||
| 213 | ttm_resource_manager_set_used(man, false); | 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 | return; | 219 | return; |
| 218 | 220 | ||
| 219 | spin_lock(&mgr->lock); | 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 | drm_mm_takedown(&mgr->mm); | 229 | drm_mm_takedown(&mgr->mm); |
| 221 | spin_unlock(&mgr->lock); | 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 | * amdgpu_vram_mgr_vis_size - Calculate visible node size | 239 | * amdgpu_vram_mgr_vis_size - Calculate visible node size |
| 231 | * | 240 | * |
| 232 | * @adev: amdgpu device structure | 241 | * @adev: amdgpu_device pointer |
| 233 | * @node: MM node structure | 242 | * @node: MM node structure |
| 234 | * | 243 | * |
| 235 | * Calculate how many bytes of the MM node are inside visible VRAM | 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 | return usage; | 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 | * amdgpu_vram_mgr_virt_start - update virtual start address | 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 | vis_usage += amdgpu_vram_mgr_vis_size(adev, nodes); | 549 | vis_usage += amdgpu_vram_mgr_vis_size(adev, nodes); |
| 446 | ++nodes; | 550 | ++nodes; |
| 447 | } | 551 | } |
| 552 | amdgpu_vram_mgr_do_reserve(man); | ||
| 448 | spin_unlock(&mgr->lock); | 553 | spin_unlock(&mgr->lock); |
| 449 | 554 | ||
| 450 | atomic64_sub(usage, &mgr->usage); | 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 | * @adev: amdgpu device pointer | 639 | * @adev: amdgpu device pointer |
| 535 | * @sgt: sg table to free | 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 | adev->df.funcs->set_fica(adev, ficaa_pie_status_in, 0, 0); | 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 | switch (adev->asic_type) { | 74 | switch (adev->asic_type) { |
| 75 | case CHIP_SIENNA_CICHLID: | 75 | case CHIP_SIENNA_CICHLID: |
| 76 | case CHIP_NAVY_FLOUNDER: | 76 | case CHIP_NAVY_FLOUNDER: |
| 77 | case CHIP_DIMGREY_CAVEFISH: | ||
| 77 | athub_v2_1_update_medium_grain_clock_gating(adev, | 78 | athub_v2_1_update_medium_grain_clock_gating(adev, |
| 78 | state == AMD_CG_STATE_GATE ? true : false); | 79 | state == AMD_CG_STATE_GATE ? true : false); |
| 79 | athub_v2_1_update_medium_grain_light_sleep(adev, | 80 | athub_v2_1_update_medium_grain_light_sleep(adev, |
| @@ -66,13 +66,13 @@ typedef struct { · 65 unmodified lines | |||
| 66 | bool abort; | 66 | bool abort; |
| 67 | } atom_exec_context; | 67 | } atom_exec_context; |
| 68 | 68 | ||
| 69 | int amdgpu_atom_debug = 0; | 69 | int amdgpu_atom_debug; |
| 70 | static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params); | 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); | 71 | int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t *params); |
| 72 | 72 | ||
| 73 | static uint32_t atom_arg_mask[8] = | 73 | static uint32_t atom_arg_mask[8] = |
| 74 | { 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000, | 74 | { 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000, |
| 75 | 0xFF000000 }; | 75 | 0xFF000000 }; |
| 76 | static int atom_arg_shift[8] = { 0, 0, 8, 16, 0, 8, 16, 24 }; | 76 | static int atom_arg_shift[8] = { 0, 0, 8, 16, 0, 8, 16, 24 }; |
| 77 | 77 | ||
| 78 | static int atom_dst_to_src[8][4] = { | 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 | static int atom_def_dst[8] = { 0, 0, 1, 2, 0, 1, 2, 3 }; | 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 | #ifdef ATOM_DEBUG | 92 | #ifdef ATOM_DEBUG |
| 93 | static void debug_print_spaces(int n) | 93 | static void debug_print_spaces(int n) |
| 94 | { | 94 | { |
| @@ -1201,7 +1201,7 @@ static struct { · 1106 unmodified lines | |||
| 1201 | atom_op_div32, ATOM_ARG_WS}, | 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 | int base = CU16(ctx->cmd_table + 4 + 2 * index); | 1206 | int base = CU16(ctx->cmd_table + 4 + 2 * index); |
| 1207 | int len, ws, ps, ptr; | 1207 | int len, ws, ps, ptr; |
| @@ -1262,7 +1262,7 @@ free: · 54 unmodified lines | |||
| 1262 | return ret; | 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 | int r; | 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 | bool amdgpu_atom_parse_data_header(struct atom_context *ctx, int index, | 1390 | bool amdgpu_atom_parse_data_header(struct atom_context *ctx, int index, |
| 1391 | uint16_t * size, uint8_t * frev, uint8_t * crev, | 1391 | uint16_t *size, uint8_t *frev, uint8_t *crev, |
| 1392 | uint16_t * data_start) | 1392 | uint16_t *data_start) |
| 1393 | { | 1393 | { |
| 1394 | int offset = index * 2 + 4; | 1394 | int offset = index * 2 + 4; |
| 1395 | int idx = CU16(ctx->data_table + offset); | 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 | return true; | 1408 | return true; |
| 1409 | } | 1409 | } |
| 1410 | 1410 | ||
| 1411 | bool amdgpu_atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev, | 1411 | bool amdgpu_atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, |
| 1412 | uint8_t * crev) | 1412 | uint8_t *crev) |
| 1413 | { | 1413 | { |
| 1414 | int offset = index * 2 + 4; | 1414 | int offset = index * 2 + 4; |
| 1415 | int idx = CU16(ctx->cmd_table + offset); | 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 | } else { | 499 | } else { |
| 500 | return ATOM_ENCODER_MODE_DVI; | 500 | return ATOM_ENCODER_MODE_DVI; |
| 501 | } | 501 | } |
| 502 | break; | ||
| 503 | case DRM_MODE_CONNECTOR_LVDS: | 502 | case DRM_MODE_CONNECTOR_LVDS: |
| 504 | return ATOM_ENCODER_MODE_LVDS; | 503 | return ATOM_ENCODER_MODE_LVDS; |
| 505 | break; | ||
| 506 | case DRM_MODE_CONNECTOR_DisplayPort: | 504 | case DRM_MODE_CONNECTOR_DisplayPort: |
| 507 | dig_connector = amdgpu_connector->con_priv; | 505 | dig_connector = amdgpu_connector->con_priv; |
| 508 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | 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 | } else { | 517 | } else { |
| 520 | return ATOM_ENCODER_MODE_DVI; | 518 | return ATOM_ENCODER_MODE_DVI; |
| 521 | } | 519 | } |
| 522 | break; | ||
| 523 | case DRM_MODE_CONNECTOR_eDP: | 520 | case DRM_MODE_CONNECTOR_eDP: |
| 524 | return ATOM_ENCODER_MODE_DP; | 521 | return ATOM_ENCODER_MODE_DP; |
| 525 | case DRM_MODE_CONNECTOR_DVIA: | 522 | case DRM_MODE_CONNECTOR_DVIA: |
| 526 | case DRM_MODE_CONNECTOR_VGA: | 523 | case DRM_MODE_CONNECTOR_VGA: |
| 527 | return ATOM_ENCODER_MODE_CRT; | 524 | return ATOM_ENCODER_MODE_CRT; |
| 528 | break; | ||
| 529 | case DRM_MODE_CONNECTOR_Composite: | 525 | case DRM_MODE_CONNECTOR_Composite: |
| 530 | case DRM_MODE_CONNECTOR_SVIDEO: | 526 | case DRM_MODE_CONNECTOR_SVIDEO: |
| 531 | case DRM_MODE_CONNECTOR_9PinDIN: | 527 | case DRM_MODE_CONNECTOR_9PinDIN: |
| 532 | /* fix me */ | 528 | /* fix me */ |
| 533 | return ATOM_ENCODER_MODE_TV; | 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 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | 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 | PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION args; | 164 | PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION args; |
| 165 | int index = GetIndexIntoMasterTable(COMMAND, ProcessI2cChannelTransaction); | 165 | int index = GetIndexIntoMasterTable(COMMAND, ProcessI2cChannelTransaction); |
| @@ -1336,11 +1336,13 @@ cik_asic_reset_method(struct amdgpu_device *adev) · 1335 unmodified lines | |||
| 1336 | 1336 | ||
| 1337 | switch (adev->asic_type) { | 1337 | switch (adev->asic_type) { |
| 1338 | case CHIP_BONAIRE: | 1338 | case CHIP_BONAIRE: |
| 1339 | case CHIP_HAWAII: | ||
| 1340 | /* disable baco reset until it works */ | 1339 | /* disable baco reset until it works */ |
| 1341 | /* smu7_asic_get_baco_capability(adev, &baco_reset); */ | 1340 | /* smu7_asic_get_baco_capability(adev, &baco_reset); */ |
| 1342 | baco_reset = false; | 1341 | baco_reset = false; |
| 1343 | break; | 1342 | break; |
| 1343 | case CHIP_HAWAII: | ||
| 1344 | baco_reset = cik_asic_supports_baco(adev); | ||
| 1345 | break; | ||
| 1344 | default: | 1346 | default: |
| 1345 | baco_reset = false; | 1347 | baco_reset = false; |
| 1346 | break; | 1348 | break; |
| @@ -195,7 +195,7 @@ static void cik_sdma_ring_set_wptr(struct amdgpu_ring *ring) · 194 unmodified lines | |||
| 195 | struct amdgpu_device *adev = ring->adev; | 195 | struct amdgpu_device *adev = ring->adev; |
| 196 | 196 | ||
| 197 | WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[ring->me], | 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 | static void cik_sdma_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) | 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 | u32 srbm_soft_reset = 0; | 1072 | u32 srbm_soft_reset = 0; |
| 1073 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 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) { | 1076 | /* sdma0 */ |
| 1077 | /* sdma0 */ | 1077 | tmp = RREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET); |
| 1078 | tmp = RREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET); | 1078 | tmp |= SDMA0_F32_CNTL__HALT_MASK; |
| 1079 | tmp |= SDMA0_F32_CNTL__HALT_MASK; | 1079 | WREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET, tmp); |
| 1080 | WREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET, tmp); | 1080 | srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA_MASK; |
| 1081 | srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA_MASK; | 1081 | |
| 1082 | } | 1082 | /* sdma1 */ |
| 1083 | if (tmp & SRBM_STATUS2__SDMA1_BUSY_MASK) { | 1083 | tmp = RREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET); |
| 1084 | /* sdma1 */ | 1084 | tmp |= SDMA0_F32_CNTL__HALT_MASK; |
| 1085 | tmp = RREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET); | 1085 | WREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET, tmp); |
| 1086 | tmp |= SDMA0_F32_CNTL__HALT_MASK; | 1086 | srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA1_MASK; |
| 1087 | WREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET, tmp); | ||
| 1088 | srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA1_MASK; | ||
| 1089 | } | ||
| 1090 | 1087 | ||
| 1091 | if (srbm_soft_reset) { | 1088 | if (srbm_soft_reset) { |
| 1092 | tmp = RREG32(mmSRBM_SOFT_RESET); | 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 | return 1; | 2202 | return 1; |
| 2203 | else | 2203 | else |
| 2204 | return 0; | 2204 | return 0; |
| 2205 | break; | ||
| 2206 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 2205 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
| 2207 | if (dig->linkb) | 2206 | if (dig->linkb) |
| 2208 | return 3; | 2207 | return 3; |
| 2209 | else | 2208 | else |
| 2210 | return 2; | 2209 | return 2; |
| 2211 | break; | ||
| 2212 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 2210 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
| 2213 | if (dig->linkb) | 2211 | if (dig->linkb) |
| 2214 | return 5; | 2212 | return 5; |
| 2215 | else | 2213 | else |
| 2216 | return 4; | 2214 | return 4; |
| 2217 | break; | ||
| 2218 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3: | 2215 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3: |
| 2219 | return 6; | 2216 | return 6; |
| 2220 | break; | ||
| 2221 | default: | 2217 | default: |
| 2222 | DRM_ERROR("invalid encoder_id: 0x%x\n", amdgpu_encoder->encoder_id); | 2218 | DRM_ERROR("invalid encoder_id: 0x%x\n", amdgpu_encoder->encoder_id); |
| 2223 | return 0; | 2219 | return 0; |
| @@ -2677,7 +2673,7 @@ static int dce_v10_0_crtc_set_base_atomic(struct drm_crtc *crtc, · 453 unmodified lines | |||
| 2677 | struct drm_framebuffer *fb, | 2673 | struct drm_framebuffer *fb, |
| 2678 | int x, int y, enum mode_set_atomic state) | 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 | static const struct drm_crtc_helper_funcs dce_v10_0_crtc_helper_funcs = { | 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 | return 1; | 2235 | return 1; |
| 2236 | else | 2236 | else |
| 2237 | return 0; | 2237 | return 0; |
| 2238 | break; | ||
| 2239 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 2238 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
| 2240 | if (dig->linkb) | 2239 | if (dig->linkb) |
| 2241 | return 3; | 2240 | return 3; |
| 2242 | else | 2241 | else |
| 2243 | return 2; | 2242 | return 2; |
| 2244 | break; | ||
| 2245 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 2243 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
| 2246 | if (dig->linkb) | 2244 | if (dig->linkb) |
| 2247 | return 5; | 2245 | return 5; |
| 2248 | else | 2246 | else |
| 2249 | return 4; | 2247 | return 4; |
| 2250 | break; | ||
| 2251 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3: | 2248 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3: |
| 2252 | return 6; | 2249 | return 6; |
| 2253 | break; | ||
| 2254 | default: | 2250 | default: |
| 2255 | DRM_ERROR("invalid encoder_id: 0x%x\n", amdgpu_encoder->encoder_id); | 2251 | DRM_ERROR("invalid encoder_id: 0x%x\n", amdgpu_encoder->encoder_id); |
| 2256 | return 0; | 2252 | return 0; |
| @@ -2304,19 +2300,16 @@ static u32 dce_v11_0_pick_pll(struct drm_crtc *crtc) · 47 unmodified lines | |||
| 2304 | return ATOM_COMBOPHY_PLL1; | 2300 | return ATOM_COMBOPHY_PLL1; |
| 2305 | else | 2301 | else |
| 2306 | return ATOM_COMBOPHY_PLL0; | 2302 | return ATOM_COMBOPHY_PLL0; |
| 2307 | break; | ||
| 2308 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 2303 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
| 2309 | if (dig->linkb) | 2304 | if (dig->linkb) |
| 2310 | return ATOM_COMBOPHY_PLL3; | 2305 | return ATOM_COMBOPHY_PLL3; |
| 2311 | else | 2306 | else |
| 2312 | return ATOM_COMBOPHY_PLL2; | 2307 | return ATOM_COMBOPHY_PLL2; |
| 2313 | break; | ||
| 2314 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 2308 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
| 2315 | if (dig->linkb) | 2309 | if (dig->linkb) |
| 2316 | return ATOM_COMBOPHY_PLL5; | 2310 | return ATOM_COMBOPHY_PLL5; |
| 2317 | else | 2311 | else |
| 2318 | return ATOM_COMBOPHY_PLL4; | 2312 | return ATOM_COMBOPHY_PLL4; |
| 2319 | break; | ||
| 2320 | default: | 2313 | default: |
| 2321 | DRM_ERROR("invalid encoder_id: 0x%x\n", amdgpu_encoder->encoder_id); | 2314 | DRM_ERROR("invalid encoder_id: 0x%x\n", amdgpu_encoder->encoder_id); |
| 2322 | return ATOM_PPLL_INVALID; | 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 | struct drm_framebuffer *fb, | 2778 | struct drm_framebuffer *fb, |
| 2786 | int x, int y, enum mode_set_atomic state) | 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 | static const struct drm_crtc_helper_funcs dce_v11_0_crtc_helper_funcs = { | 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 | struct drm_framebuffer *fb, | 2567 | struct drm_framebuffer *fb, |
| 2568 | int x, int y, enum mode_set_atomic state) | 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 | static const struct drm_crtc_helper_funcs dce_v6_0_crtc_helper_funcs = { | 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 | case ATOM_PPLL2: | 2498 | case ATOM_PPLL2: |
| 2499 | /* disable the ppll */ | 2499 | /* disable the ppll */ |
| 2500 | amdgpu_atombios_crtc_program_pll(crtc, amdgpu_crtc->crtc_id, amdgpu_crtc->pll_id, | 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 | break; | 2502 | break; |
| 2503 | case ATOM_PPLL0: | 2503 | case ATOM_PPLL0: |
| 2504 | /* disable the ppll */ | 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 | struct drm_framebuffer *fb, | 2585 | struct drm_framebuffer *fb, |
| 2586 | int x, int y, enum mode_set_atomic state) | 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 | static const struct drm_crtc_helper_funcs dce_v8_0_crtc_helper_funcs = { | 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 | static void df_v1_7_enable_broadcast_mode(struct amdgpu_device *adev, | 43 | static void df_v1_7_enable_broadcast_mode(struct amdgpu_device *adev, |
| 44 | bool enable) | 44 | bool enable) |
| 45 | { | 45 | { |
| 46 | u32 tmp; | 46 | u32 tmp; |
| 47 | 47 | ||
| @@ -30,71 +30,17 @@ · 29 unmodified lines | |||
| 30 | #define DF_3_6_SMN_REG_INST_DIST 0x8 | 30 | #define DF_3_6_SMN_REG_INST_DIST 0x8 |
| 31 | #define DF_3_6_INST_CNT 8 | 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, | 33 | /* Defined in global_features.h as FTI_PERFMON_VISIBLE */ |
| 34 | 16, 32, 0, 0, 0, 2, 4, 8}; | 34 | #define DF_V3_6_MAX_COUNTERS 4 |
| 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 | }; | ||
| 85 | 35 | ||
| 86 | /* df event attribute group */ | 36 | /* get flags from df perfmon config */ |
| 87 | static struct attribute_group df_v3_6_event_attr_group = { | 37 | #define DF_V3_6_GET_EVENT(x) (x & 0xFFUL) |
| 88 | .name = "events", | 38 | #define DF_V3_6_GET_INSTANCE(x) ((x >> 8) & 0xFFUL) |
| 89 | .attrs = df_v3_6_event_attrs | 39 | #define DF_V3_6_GET_UNITMASK(x) ((x >> 16) & 0xFFUL) |
| 90 | }; | 40 | #define DF_V3_6_PERFMON_OVERFLOW 0xFFFFFFFFFFFFULL |
| 91 | 41 | ||
| 92 | /* df event attr groups */ | 42 | static u32 df_v3_6_channel_number[] = {1, 2, 0, 4, 0, 8, 0, |
| 93 | const struct attribute_group *df_v3_6_attr_groups[] = { | 43 | 16, 32, 0, 0, 0, 2, 4, 8}; |
| 94 | &df_v3_6_format_attr_group, | ||
| 95 | &df_v3_6_event_attr_group, | ||
| 96 | NULL | ||
| 97 | }; | ||
| 98 | 44 | ||
| 99 | static uint64_t df_v3_6_get_fica(struct amdgpu_device *adev, | 45 | static uint64_t df_v3_6_get_fica(struct amdgpu_device *adev, |
| 100 | uint32_t ficaa_val) | 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 | /* get assigned df perfmon ctr as int */ | 339 | /* get assigned df perfmon ctr as int */ |
| 394 | static int df_v3_6_pmc_config_2_cntr(struct amdgpu_device *adev, | 340 | static bool df_v3_6_pmc_has_counter(struct amdgpu_device *adev, |
| 395 | uint64_t config) | 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++) { | 345 | return ((config & 0x0FFFFFFUL) == |
| 400 | if ((config & 0x0FFFFFFUL) == | 346 | adev->df_perfmon_config_assign_mask[counter_idx]); |
| 401 | adev->df_perfmon_config_assign_mask[i]) | ||
| 402 | return i; | ||
| 403 | } | ||
| 404 | 347 | ||
| 405 | return -EINVAL; | ||
| 406 | } | 348 | } |
| 407 | 349 | ||
| 408 | /* get address based on counter assignment */ | 350 | /* get address based on counter assignment */ |
| 409 | static void df_v3_6_pmc_get_addr(struct amdgpu_device *adev, | 351 | static void df_v3_6_pmc_get_addr(struct amdgpu_device *adev, |
| 410 | uint64_t config, | 352 | uint64_t config, |
| 353 | int counter_idx, | ||
| 411 | int is_ctrl, | 354 | int is_ctrl, |
| 412 | uint32_t *lo_base_addr, | 355 | uint32_t *lo_base_addr, |
| 413 | uint32_t *hi_base_addr) | 356 | uint32_t *hi_base_addr) |
| 414 | { | 357 | { |
| 415 | int target_cntr = df_v3_6_pmc_config_2_cntr(adev, config); | 358 | if (!df_v3_6_pmc_has_counter(adev, config, counter_idx)) |
| 416 | |||
| 417 | if (target_cntr < 0) | ||
| 418 | return; | 359 | return; |
| 419 | 360 | ||
| 420 | switch (target_cntr) { | 361 | switch (counter_idx) { |
| 421 | 362 | ||
| 422 | case 0: | 363 | case 0: |
| 423 | *lo_base_addr = is_ctrl ? smnPerfMonCtlLo4 : smnPerfMonCtrLo4; | 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 | /* get read counter address */ | 384 | /* get read counter address */ |
| 444 | static void df_v3_6_pmc_get_read_settings(struct amdgpu_device *adev, | 385 | static void df_v3_6_pmc_get_read_settings(struct amdgpu_device *adev, |
| 445 | uint64_t config, | 386 | uint64_t config, |
| 387 | int counter_idx, | ||
| 446 | uint32_t *lo_base_addr, | 388 | uint32_t *lo_base_addr, |
| 447 | uint32_t *hi_base_addr) | 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 | /* get control counter settings i.e. address and values to set */ | 395 | /* get control counter settings i.e. address and values to set */ |
| 453 | static int df_v3_6_pmc_get_ctrl_settings(struct amdgpu_device *adev, | 396 | static int df_v3_6_pmc_get_ctrl_settings(struct amdgpu_device *adev, |
| 454 | uint64_t config, | 397 | uint64_t config, |
| 398 | int counter_idx, | ||
| 455 | uint32_t *lo_base_addr, | 399 | uint32_t *lo_base_addr, |
| 456 | uint32_t *hi_base_addr, | 400 | uint32_t *hi_base_addr, |
| 457 | uint32_t *lo_val, | 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 | uint32_t eventsel, instance, unitmask; | 406 | uint32_t eventsel, instance, unitmask; |
| 463 | uint32_t instance_10, instance_5432, instance_76; | 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 | if ((*lo_base_addr == 0) || (*hi_base_addr == 0)) { | 412 | if ((*lo_base_addr == 0) || (*hi_base_addr == 0)) { |
| 468 | DRM_ERROR("[DF PMC] addressing not retrieved! Lo: %x, Hi: %x", | 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 | static int df_v3_6_pmc_add_cntr(struct amdgpu_device *adev, | 437 | static int df_v3_6_pmc_add_cntr(struct amdgpu_device *adev, |
| 493 | uint64_t config) | 438 | uint64_t config) |
| 494 | { | 439 | { |
| 495 | int i, target_cntr; | 440 | int i; |
| 496 | |||
| 497 | target_cntr = df_v3_6_pmc_config_2_cntr(adev, config); | ||
| 498 | |||
| 499 | if (target_cntr >= 0) | ||
| 500 | return 0; | ||
| 501 | 441 | ||
| 502 | for (i = 0; i < DF_V3_6_MAX_COUNTERS; i++) { | 442 | for (i = 0; i < DF_V3_6_MAX_COUNTERS; i++) { |
| 503 | if (adev->df_perfmon_config_assign_mask[i] == 0U) { | 443 | if (adev->df_perfmon_config_assign_mask[i] == 0U) { |
| 504 | adev->df_perfmon_config_assign_mask[i] = | 444 | adev->df_perfmon_config_assign_mask[i] = |
| 505 | config & 0x0FFFFFFUL; | 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 | #define DEFERRED_ARM_MASK (1 << 31) | 453 | #define DEFERRED_ARM_MASK (1 << 31) |
| 514 | static int df_v3_6_pmc_set_deferred(struct amdgpu_device *adev, | 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); | 459 | if (!df_v3_6_pmc_has_counter(adev, config, counter_idx)) |
| 520 | |||
| 521 | if (target_cntr < 0) | ||
| 522 | return -EINVAL; | 460 | return -EINVAL; |
| 523 | 461 | ||
| 524 | if (is_deferred) | 462 | if (is_deferred) |
| 525 | adev->df_perfmon_config_assign_mask[target_cntr] |= | 463 | adev->df_perfmon_config_assign_mask[counter_idx] |= |
| 526 | DEFERRED_ARM_MASK; | 464 | DEFERRED_ARM_MASK; |
| 527 | else | 465 | else |
| 528 | adev->df_perfmon_config_assign_mask[target_cntr] &= | 466 | adev->df_perfmon_config_assign_mask[counter_idx] &= |
| 529 | ~DEFERRED_ARM_MASK; | 467 | ~DEFERRED_ARM_MASK; |
| 530 | 468 | ||
| 531 | return 0; | 469 | return 0; |
| 532 | } | 470 | } |
| 533 | 471 | ||
| 534 | static bool df_v3_6_pmc_is_deferred(struct amdgpu_device *adev, | 472 | static bool df_v3_6_pmc_is_deferred(struct amdgpu_device *adev, |
| 473 | int counter_idx, | ||
| 535 | uint64_t config) | 474 | uint64_t config) |
| 536 | { | 475 | { |
| 537 | int target_cntr; | 476 | return (df_v3_6_pmc_has_counter(adev, config, counter_idx) && |
| 538 | 477 | (adev->df_perfmon_config_assign_mask[counter_idx] | |
| 539 | target_cntr = df_v3_6_pmc_config_2_cntr(adev, config); | 478 | & DEFERRED_ARM_MASK)); |
| 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)); | ||
| 548 | 479 | ||
| 549 | } | 480 | } |
| 550 | 481 | ||
| 551 | /* release performance counter */ | 482 | /* release performance counter */ |
| 552 | static void df_v3_6_pmc_release_cntr(struct amdgpu_device *adev, | 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); | 487 | if (df_v3_6_pmc_has_counter(adev, config, counter_idx)) |
| 556 | 488 | adev->df_perfmon_config_assign_mask[counter_idx] = 0ULL; | |
| 557 | if (target_cntr >= 0) | ||
| 558 | adev->df_perfmon_config_assign_mask[target_cntr] = 0ULL; | ||
| 559 | } | 489 | } |
| 560 | 490 | ||
| 561 | 491 | ||
| 562 | static void df_v3_6_reset_perfmon_cntr(struct amdgpu_device *adev, | 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 | uint32_t lo_base_addr = 0, hi_base_addr = 0; | 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 | &hi_base_addr); | 499 | &hi_base_addr); |
| 569 | 500 | ||
| 570 | if ((lo_base_addr == 0) || (hi_base_addr == 0)) | 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 | df_v3_6_perfmon_wreg(adev, lo_base_addr, 0, hi_base_addr, 0); | 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 | static int df_v3_6_pmc_start(struct amdgpu_device *adev, uint64_t config, | 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 | uint32_t lo_base_addr, hi_base_addr, lo_val, hi_val; | 511 | uint32_t lo_base_addr, hi_base_addr, lo_val, hi_val; |
| 580 | int err = 0, ret = 0; | 512 | int err = 0, ret = 0; |
| 581 | 513 | ||
| 582 | switch (adev->asic_type) { | 514 | switch (adev->asic_type) { |
| 583 | case CHIP_VEGA20: | 515 | case CHIP_VEGA20: |
| 516 | case CHIP_ARCTURUS: | ||
| 584 | if (is_add) | 517 | if (is_add) |
| 585 | return df_v3_6_pmc_add_cntr(adev, config); | 518 | return df_v3_6_pmc_add_cntr(adev, config); |
| 586 | 519 | ||
| 587 | df_v3_6_reset_perfmon_cntr(adev, config); | ||
| 588 | |||
| 589 | ret = df_v3_6_pmc_get_ctrl_settings(adev, | 520 | ret = df_v3_6_pmc_get_ctrl_settings(adev, |
| 590 | config, | 521 | config, |
| 522 | counter_idx, | ||
| 591 | &lo_base_addr, | 523 | &lo_base_addr, |
| 592 | &hi_base_addr, | 524 | &hi_base_addr, |
| 593 | &lo_val, | 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 | hi_val); | 536 | hi_val); |
| 605 | 537 | ||
| 606 | if (err) | 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 | break; | 542 | break; |
| 610 | default: | 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 | static int df_v3_6_pmc_stop(struct amdgpu_device *adev, uint64_t config, | 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 | uint32_t lo_base_addr, hi_base_addr, lo_val, hi_val; | 553 | uint32_t lo_base_addr, hi_base_addr, lo_val, hi_val; |
| 621 | int ret = 0; | 554 | int ret = 0; |
| 622 | 555 | ||
| 623 | switch (adev->asic_type) { | 556 | switch (adev->asic_type) { |
| 624 | case CHIP_VEGA20: | 557 | case CHIP_VEGA20: |
| 558 | case CHIP_ARCTURUS: | ||
| 625 | ret = df_v3_6_pmc_get_ctrl_settings(adev, | 559 | ret = df_v3_6_pmc_get_ctrl_settings(adev, |
| 626 | config, | 560 | config, |
| 561 | counter_idx, | ||
| 627 | &lo_base_addr, | 562 | &lo_base_addr, |
| 628 | &hi_base_addr, | 563 | &hi_base_addr, |
| 629 | &lo_val, | 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 | if (is_remove) { | 572 | if (is_remove) { |
| 638 | df_v3_6_reset_perfmon_cntr(adev, config); | 573 | df_v3_6_reset_perfmon_cntr(adev, config, counter_idx); |
| 639 | df_v3_6_pmc_release_cntr(adev, config); | 574 | df_v3_6_pmc_release_cntr(adev, config, counter_idx); |
| 640 | } | 575 | } |
| 641 | 576 | ||
| 642 | break; | 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 | static void df_v3_6_pmc_get_count(struct amdgpu_device *adev, | 585 | static void df_v3_6_pmc_get_count(struct amdgpu_device *adev, |
| 651 | uint64_t config, | 586 | uint64_t config, |
| 587 | int counter_idx, | ||
| 652 | uint64_t *count) | 588 | uint64_t *count) |
| 653 | { | 589 | { |
| 654 | uint32_t lo_base_addr = 0, hi_base_addr = 0, lo_val = 0, hi_val = 0; | 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 | switch (adev->asic_type) { | 593 | switch (adev->asic_type) { |
| 658 | case CHIP_VEGA20: | 594 | case CHIP_VEGA20: |
| 659 | df_v3_6_pmc_get_read_settings(adev, config, &lo_base_addr, | 595 | case CHIP_ARCTURUS: |
| 660 | &hi_base_addr); | 596 | df_v3_6_pmc_get_read_settings(adev, config, counter_idx, |
| 597 | &lo_base_addr, &hi_base_addr); | ||
| 661 | 598 | ||
| 662 | if ((lo_base_addr == 0) || (hi_base_addr == 0)) | 599 | if ((lo_base_addr == 0) || (hi_base_addr == 0)) |
| 663 | return; | 600 | return; |
| 664 | 601 | ||
| 665 | /* rearm the counter or throw away count value on failure */ | 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 | int rearm_err = df_v3_6_perfmon_arm_with_status(adev, | 604 | int rearm_err = df_v3_6_perfmon_arm_with_status(adev, |
| 668 | lo_base_addr, lo_val, | 605 | lo_base_addr, lo_val, |
| 669 | hi_base_addr, hi_val); | 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 | if (rearm_err) | 608 | if (rearm_err) |
| 672 | return; | 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 | df_v3_6_perfmon_rreg(adev, lo_base_addr, &lo_val, | 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 | DF_V3_6_MGCG_ENABLE_63_CYCLE_DELAY = 15 | 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 | extern const struct attribute_group *df_v3_6_attr_groups[]; | 38 | extern const struct attribute_group *df_v3_6_attr_groups[]; |
| 48 | extern const struct amdgpu_df_funcs df_v3_6_funcs; | 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 | #define mmGCR_GENERAL_CNTL_Sienna_Cichlid 0x1580 | 99 | #define mmGCR_GENERAL_CNTL_Sienna_Cichlid 0x1580 |
| 100 | #define mmGCR_GENERAL_CNTL_Sienna_Cichlid_BASE_IDX 0 | 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 | #define mmCP_HYP_PFP_UCODE_ADDR 0x5814 | 119 | #define mmCP_HYP_PFP_UCODE_ADDR 0x5814 |
| 103 | #define mmCP_HYP_PFP_UCODE_ADDR_BASE_IDX 1 | 120 | #define mmCP_HYP_PFP_UCODE_ADDR_BASE_IDX 1 |
| 104 | #define mmCP_HYP_PFP_UCODE_DATA 0x5815 | 121 | #define mmCP_HYP_PFP_UCODE_DATA 0x5815 |
| @@ -112,6 +129,13 @@ · 7 unmodified lines | |||
| 112 | #define mmCP_HYP_ME_UCODE_DATA 0x5817 | 129 | #define mmCP_HYP_ME_UCODE_DATA 0x5817 |
| 113 | #define mmCP_HYP_ME_UCODE_DATA_BASE_IDX 1 | 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 | //CC_GC_SA_UNIT_DISABLE | 139 | //CC_GC_SA_UNIT_DISABLE |
| 116 | #define mmCC_GC_SA_UNIT_DISABLE 0x0fe9 | 140 | #define mmCC_GC_SA_UNIT_DISABLE 0x0fe9 |
| 117 | #define mmCC_GC_SA_UNIT_DISABLE_BASE_IDX 0 | 141 | #define mmCC_GC_SA_UNIT_DISABLE_BASE_IDX 0 |
| @@ -128,6 +152,9 @@ · 10 unmodified lines | |||
| 128 | #define PA_SC_ENHANCE_3__FORCE_PBB_WORKLOAD_MODE_TO_ZERO__SHIFT 0x3 | 152 | #define PA_SC_ENHANCE_3__FORCE_PBB_WORKLOAD_MODE_TO_ZERO__SHIFT 0x3 |
| 129 | #define PA_SC_ENHANCE_3__FORCE_PBB_WORKLOAD_MODE_TO_ZERO_MASK 0x00000008L | 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 | MODULE_FIRMWARE("amdgpu/navi10_ce.bin"); | 158 | MODULE_FIRMWARE("amdgpu/navi10_ce.bin"); |
| 132 | MODULE_FIRMWARE("amdgpu/navi10_pfp.bin"); | 159 | MODULE_FIRMWARE("amdgpu/navi10_pfp.bin"); |
| 133 | MODULE_FIRMWARE("amdgpu/navi10_me.bin"); | 160 | MODULE_FIRMWARE("amdgpu/navi10_me.bin"); |
| @@ -168,6 +195,20 @@ MODULE_FIRMWARE("amdgpu/navy_flounder_mec.bin"); · 34 unmodified lines | |||
| 168 | MODULE_FIRMWARE("amdgpu/navy_flounder_mec2.bin"); | 195 | MODULE_FIRMWARE("amdgpu/navy_flounder_mec2.bin"); |
| 169 | MODULE_FIRMWARE("amdgpu/navy_flounder_rlc.bin"); | 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 | static const struct soc15_reg_golden golden_settings_gc_10_1[] = | 212 | static const struct soc15_reg_golden golden_settings_gc_10_1[] = |
| 172 | { | 213 | { |
| 173 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0xffffffff, 0x00400014), | 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 | static const struct soc15_reg_golden golden_settings_gc_10_3[] = | 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 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_PS_CLK_CTRL, 0xff7f0fff, 0x78000100), | 3139 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_PS_CLK_CTRL, 0xff7f0fff, 0x78000100), |
| 3098 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_RA0_CLK_CTRL, 0xff7f0fff, 0x30000100), | 3140 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_RA0_CLK_CTRL, 0xff7f0fff, 0x30000100), |
| 3099 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_RA1_CLK_CTRL, 0xff7f0fff, 0x7e000100), | 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 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER9_SELECT, 0xf0f001ff, 0x00000000), | 3219 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER9_SELECT, 0xf0f001ff, 0x00000000), |
| 3178 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfff7ffff, 0x01030000), | 3220 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfff7ffff, 0x01030000), |
| 3179 | SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffbfffff, 0x00a00000), | 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 | #define DEFAULT_SH_MEM_CONFIG \ | 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 | static void gfx_v10_0_set_gds_init(struct amdgpu_device *adev); | 3301 | static void gfx_v10_0_set_gds_init(struct amdgpu_device *adev); |
| 3193 | static void gfx_v10_0_set_rlc_funcs(struct amdgpu_device *adev); | 3302 | static void gfx_v10_0_set_rlc_funcs(struct amdgpu_device *adev); |
| 3194 | static int gfx_v10_0_get_cu_info(struct amdgpu_device *adev, | 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 | static uint64_t gfx_v10_0_get_gpu_clock_counter(struct amdgpu_device *adev); | 3305 | static uint64_t gfx_v10_0_get_gpu_clock_counter(struct amdgpu_device *adev); |
| 3197 | static void gfx_v10_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, | 3306 | static void gfx_v10_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, |
| 3198 | u32 sh_num, u32 instance); | 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 | golden_settings_gc_10_3_2, | 3498 | golden_settings_gc_10_3_2, |
| 3390 | (const u32)ARRAY_SIZE(golden_settings_gc_10_3_2)); | 3499 | (const u32)ARRAY_SIZE(golden_settings_gc_10_3_2)); |
| 3391 | break; | 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 | default: | 3511 | default: |
| 3394 | break; | 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 | break; | 3691 | break; |
| 3574 | case CHIP_SIENNA_CICHLID: | 3692 | case CHIP_SIENNA_CICHLID: |
| 3575 | case CHIP_NAVY_FLOUNDER: | 3693 | case CHIP_NAVY_FLOUNDER: |
| 3694 | case CHIP_VANGOGH: | ||
| 3695 | case CHIP_DIMGREY_CAVEFISH: | ||
| 3576 | adev->gfx.cp_fw_write_wait = true; | 3696 | adev->gfx.cp_fw_write_wait = true; |
| 3577 | break; | 3697 | break; |
| 3578 | default: | 3698 | default: |
| @@ -3640,7 +3760,7 @@ static void gfx_v10_0_check_gfxoff_flag(struct amdgpu_device *adev) · 61 unmodified lines | |||
| 3640 | if (!gfx_v10_0_navi10_gfxoff_should_enable(adev)) | 3760 | if (!gfx_v10_0_navi10_gfxoff_should_enable(adev)) |
| 3641 | adev->pm.pp_feature &= ~PP_GFXOFF_MASK; | 3761 | adev->pm.pp_feature &= ~PP_GFXOFF_MASK; |
| 3642 | break; | 3762 | break; |
| 3643 | case CHIP_NAVY_FLOUNDER: | 3763 | case CHIP_VANGOGH: |
| 3644 | adev->pm.pp_feature &= ~PP_GFXOFF_MASK; | 3764 | adev->pm.pp_feature &= ~PP_GFXOFF_MASK; |
| 3645 | break; | 3765 | break; |
| 3646 | default: | 3766 | default: |
| @@ -3685,6 +3805,12 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev) · 38 unmodified lines | |||
| 3685 | case CHIP_NAVY_FLOUNDER: | 3805 | case CHIP_NAVY_FLOUNDER: |
| 3686 | chip_name = "navy_flounder"; | 3806 | chip_name = "navy_flounder"; |
| 3687 | break; | 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 | default: | 3814 | default: |
| 3689 | BUG(); | 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 | static void gfx_v10_0_select_me_pipe_q(struct amdgpu_device *adev, | 4328 | static void gfx_v10_0_select_me_pipe_q(struct amdgpu_device *adev, |
| 4203 | u32 me, u32 pipe, u32 q, u32 vm) | 4329 | u32 me, u32 pipe, u32 q, u32 vm) |
| 4204 | { | 4330 | { |
| 4205 | nv_grbm_select(adev, me, pipe, q, vm); | 4331 | nv_grbm_select(adev, me, pipe, q, vm); |
| 4206 | } | 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 | static const struct amdgpu_gfx_funcs gfx_v10_0_gfx_funcs = { | 4350 | static const struct amdgpu_gfx_funcs gfx_v10_0_gfx_funcs = { |
| 4210 | .get_gpu_clock_counter = &gfx_v10_0_get_gpu_clock_counter, | 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 | .read_wave_vgprs = &gfx_v10_0_read_wave_vgprs, | 4355 | .read_wave_vgprs = &gfx_v10_0_read_wave_vgprs, |
| 4215 | .select_me_pipe_q = &gfx_v10_0_select_me_pipe_q, | 4356 | .select_me_pipe_q = &gfx_v10_0_select_me_pipe_q, |
| 4216 | .init_spm_golden = &gfx_v10_0_init_spm_golden_registers, | 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 | static void gfx_v10_0_gpu_early_init(struct amdgpu_device *adev) | 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 | break; | 4377 | break; |
| 4236 | case CHIP_SIENNA_CICHLID: | 4378 | case CHIP_SIENNA_CICHLID: |
| 4237 | case CHIP_NAVY_FLOUNDER: | 4379 | case CHIP_NAVY_FLOUNDER: |
| 4380 | case CHIP_VANGOGH: | ||
| 4381 | case CHIP_DIMGREY_CAVEFISH: | ||
| 4238 | adev->gfx.config.max_hw_contexts = 8; | 4382 | adev->gfx.config.max_hw_contexts = 8; |
| 4239 | adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; | 4383 | adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; |
| 4240 | adev->gfx.config.sc_prim_fifo_size_backend = 0x100; | 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 | break; | 4502 | break; |
| 4359 | case CHIP_SIENNA_CICHLID: | 4503 | case CHIP_SIENNA_CICHLID: |
| 4360 | case CHIP_NAVY_FLOUNDER: | 4504 | case CHIP_NAVY_FLOUNDER: |
| 4505 | case CHIP_VANGOGH: | ||
| 4506 | case CHIP_DIMGREY_CAVEFISH: | ||
| 4361 | adev->gfx.me.num_me = 1; | 4507 | adev->gfx.me.num_me = 1; |
| 4362 | adev->gfx.me.num_pipe_per_me = 1; | 4508 | adev->gfx.me.num_pipe_per_me = 1; |
| 4363 | adev->gfx.me.num_queue_per_pipe = 1; | 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 | /* for ASICs that integrates GFX v10.3 | 4764 | /* for ASICs that integrates GFX v10.3 |
| 4619 | * pa_sc_tile_steering_override should be set to 0 */ | 4765 | * pa_sc_tile_steering_override should be set to 0 */ |
| 4620 | if (adev->asic_type == CHIP_SIENNA_CICHLID || | 4766 | if (adev->asic_type >= CHIP_SIENNA_CICHLID) |
| 4621 | adev->asic_type == CHIP_NAVY_FLOUNDER) | ||
| 4622 | return 0; | 4767 | return 0; |
| 4623 | 4768 | ||
| 4624 | /* init num_sc */ | 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 | switch (adev->asic_type) { | 6000 | switch (adev->asic_type) { |
| 5856 | case CHIP_SIENNA_CICHLID: | 6001 | case CHIP_SIENNA_CICHLID: |
| 5857 | case CHIP_NAVY_FLOUNDER: | 6002 | case CHIP_NAVY_FLOUNDER: |
| 6003 | case CHIP_VANGOGH: | ||
| 6004 | case CHIP_DIMGREY_CAVEFISH: | ||
| 5858 | tmp = REG_SET_FIELD(0, CP_RB_DOORBELL_RANGE_LOWER, | 6005 | tmp = REG_SET_FIELD(0, CP_RB_DOORBELL_RANGE_LOWER, |
| 5859 | DOORBELL_RANGE_LOWER_Sienna_Cichlid, ring->doorbell_index); | 6006 | DOORBELL_RANGE_LOWER_Sienna_Cichlid, ring->doorbell_index); |
| 5860 | WREG32_SOC15(GC, 0, mmCP_RB_DOORBELL_RANGE_LOWER, tmp); | 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 | switch (adev->asic_type) { | 6135 | switch (adev->asic_type) { |
| 5989 | case CHIP_SIENNA_CICHLID: | 6136 | case CHIP_SIENNA_CICHLID: |
| 5990 | case CHIP_NAVY_FLOUNDER: | 6137 | case CHIP_NAVY_FLOUNDER: |
| 6138 | case CHIP_VANGOGH: | ||
| 6139 | case CHIP_DIMGREY_CAVEFISH: | ||
| 5991 | WREG32_SOC15(GC, 0, mmCP_MEC_CNTL_Sienna_Cichlid, 0); | 6140 | WREG32_SOC15(GC, 0, mmCP_MEC_CNTL_Sienna_Cichlid, 0); |
| 5992 | break; | 6141 | break; |
| 5993 | default: | 6142 | default: |
| @@ -5998,6 +6147,8 @@ static void gfx_v10_0_cp_compute_enable(struct amdgpu_device *adev, bool enable) · 4 unmodified lines | |||
| 5998 | switch (adev->asic_type) { | 6147 | switch (adev->asic_type) { |
| 5999 | case CHIP_SIENNA_CICHLID: | 6148 | case CHIP_SIENNA_CICHLID: |
| 6000 | case CHIP_NAVY_FLOUNDER: | 6149 | case CHIP_NAVY_FLOUNDER: |
| 6150 | case CHIP_VANGOGH: | ||
| 6151 | case CHIP_DIMGREY_CAVEFISH: | ||
| 6001 | WREG32_SOC15(GC, 0, mmCP_MEC_CNTL_Sienna_Cichlid, | 6152 | WREG32_SOC15(GC, 0, mmCP_MEC_CNTL_Sienna_Cichlid, |
| 6002 | (CP_MEC_CNTL__MEC_ME1_HALT_MASK | | 6153 | (CP_MEC_CNTL__MEC_ME1_HALT_MASK | |
| 6003 | CP_MEC_CNTL__MEC_ME2_HALT_MASK)); | 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 | switch (adev->asic_type) { | 6243 | switch (adev->asic_type) { |
| 6093 | case CHIP_SIENNA_CICHLID: | 6244 | case CHIP_SIENNA_CICHLID: |
| 6094 | case CHIP_NAVY_FLOUNDER: | 6245 | case CHIP_NAVY_FLOUNDER: |
| 6246 | case CHIP_VANGOGH: | ||
| 6247 | case CHIP_DIMGREY_CAVEFISH: | ||
| 6095 | tmp = RREG32_SOC15(GC, 0, mmRLC_CP_SCHEDULERS_Sienna_Cichlid); | 6248 | tmp = RREG32_SOC15(GC, 0, mmRLC_CP_SCHEDULERS_Sienna_Cichlid); |
| 6096 | tmp &= 0xffffff00; | 6249 | tmp &= 0xffffff00; |
| 6097 | tmp |= (ring->me << 5) | (ring->pipe << 3) | (ring->queue); | 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 | switch (adev->asic_type) { | 6953 | switch (adev->asic_type) { |
| 6801 | case CHIP_SIENNA_CICHLID: | 6954 | case CHIP_SIENNA_CICHLID: |
| 6802 | case CHIP_NAVY_FLOUNDER: | 6955 | case CHIP_NAVY_FLOUNDER: |
| 6956 | case CHIP_DIMGREY_CAVEFISH: | ||
| 6803 | data = RREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE_Sienna_Cichlid); | 6957 | data = RREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE_Sienna_Cichlid); |
| 6804 | WREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE_Sienna_Cichlid, 0); | 6958 | WREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE_Sienna_Cichlid, 0); |
| 6805 | WREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE_UMD, pattern); | 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 | return false; | 6966 | return false; |
| 6813 | } | 6967 | } |
| 6814 | break; | 6968 | break; |
| 6969 | case CHIP_VANGOGH: | ||
| 6970 | return true; | ||
| 6815 | default: | 6971 | default: |
| 6816 | data = RREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE); | 6972 | data = RREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE); |
| 6817 | WREG32_SOC15(GC, 0, mmVGT_ESGS_RING_SIZE, 0); | 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 | switch (adev->asic_type) { | 6995 | switch (adev->asic_type) { |
| 6840 | case CHIP_SIENNA_CICHLID: | 6996 | case CHIP_SIENNA_CICHLID: |
| 6841 | case CHIP_NAVY_FLOUNDER: | 6997 | case CHIP_NAVY_FLOUNDER: |
| 6998 | case CHIP_VANGOGH: | ||
| 6999 | case CHIP_DIMGREY_CAVEFISH: | ||
| 6842 | /* mmVGT_TF_RING_SIZE_UMD -> mmVGT_TF_RING_SIZE */ | 7000 | /* mmVGT_TF_RING_SIZE_UMD -> mmVGT_TF_RING_SIZE */ |
| 6843 | data = (SOC15_REG_OFFSET(GC, 0, mmVGT_TF_RING_SIZE_UMD) << | 7001 | data = (SOC15_REG_OFFSET(GC, 0, mmVGT_TF_RING_SIZE_UMD) << |
| 6844 | GRBM_CAM_DATA__CAM_ADDR__SHIFT) | | 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 | WREG32_SOC15(GC, 0, mmGRBM_CAM_DATA, data); | 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 | static int gfx_v10_0_hw_init(void *handle) | 7127 | static int gfx_v10_0_hw_init(void *handle) |
| 6958 | { | 7128 | { |
| 6959 | int r; | 7129 | int r; |
| @@ -6968,7 +7138,7 @@ static int gfx_v10_0_hw_init(void *handle) · 8 unmodified lines | |||
| 6968 | * loaded firstly, so in direct type, it has to load smc ucode | 7138 | * loaded firstly, so in direct type, it has to load smc ucode |
| 6969 | * here before rlc. | 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 | r = smu_load_microcode(&adev->smu); | 7142 | r = smu_load_microcode(&adev->smu); |
| 6973 | if (r) | 7143 | if (r) |
| 6974 | return r; | 7144 | return r; |
| @@ -6979,6 +7149,7 @@ static int gfx_v10_0_hw_init(void *handle) · 4 unmodified lines | |||
| 6979 | return r; | 7149 | return r; |
| 6980 | } | 7150 | } |
| 6981 | } | 7151 | } |
| 7152 | gfx_v10_0_disable_gpa_mode(adev); | ||
| 6982 | } | 7153 | } |
| 6983 | 7154 | ||
| 6984 | /* if GRBM CAM not remapped, set up the remapping */ | 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 | switch (adev->asic_type) { | 7307 | switch (adev->asic_type) { |
| 7137 | case CHIP_SIENNA_CICHLID: | 7308 | case CHIP_SIENNA_CICHLID: |
| 7138 | case CHIP_NAVY_FLOUNDER: | 7309 | case CHIP_NAVY_FLOUNDER: |
| 7310 | case CHIP_VANGOGH: | ||
| 7311 | case CHIP_DIMGREY_CAVEFISH: | ||
| 7139 | if (REG_GET_FIELD(tmp, GRBM_STATUS2, RLC_BUSY_Sienna_Cichlid)) | 7312 | if (REG_GET_FIELD(tmp, GRBM_STATUS2, RLC_BUSY_Sienna_Cichlid)) |
| 7140 | grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, | 7313 | grbm_soft_reset = REG_SET_FIELD(grbm_soft_reset, |
| 7141 | GRBM_SOFT_RESET, | 7314 | GRBM_SOFT_RESET, |
| @@ -7235,13 +7408,16 @@ static int gfx_v10_0_early_init(void *handle) · 93 unmodified lines | |||
| 7235 | break; | 7408 | break; |
| 7236 | case CHIP_SIENNA_CICHLID: | 7409 | case CHIP_SIENNA_CICHLID: |
| 7237 | case CHIP_NAVY_FLOUNDER: | 7410 | case CHIP_NAVY_FLOUNDER: |
| 7411 | case CHIP_VANGOGH: | ||
| 7412 | case CHIP_DIMGREY_CAVEFISH: | ||
| 7238 | adev->gfx.num_gfx_rings = GFX10_NUM_GFX_RINGS_Sienna_Cichlid; | 7413 | adev->gfx.num_gfx_rings = GFX10_NUM_GFX_RINGS_Sienna_Cichlid; |
| 7239 | break; | 7414 | break; |
| 7240 | default: | 7415 | default: |
| 7241 | break; | 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 | gfx_v10_0_set_kiq_pm4_funcs(adev); | 7422 | gfx_v10_0_set_kiq_pm4_funcs(adev); |
| 7247 | gfx_v10_0_set_ring_funcs(adev); | 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 | switch (adev->asic_type) { | 7464 | switch (adev->asic_type) { |
| 7289 | case CHIP_SIENNA_CICHLID: | 7465 | case CHIP_SIENNA_CICHLID: |
| 7290 | case CHIP_NAVY_FLOUNDER: | 7466 | case CHIP_NAVY_FLOUNDER: |
| 7467 | case CHIP_VANGOGH: | ||
| 7468 | case CHIP_DIMGREY_CAVEFISH: | ||
| 7291 | WREG32_SOC15(GC, 0, mmRLC_SAFE_MODE_Sienna_Cichlid, data); | 7469 | WREG32_SOC15(GC, 0, mmRLC_SAFE_MODE_Sienna_Cichlid, data); |
| 7292 | 7470 | ||
| 7293 | /* wait for RLC_SAFE_MODE */ | 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 | switch (adev->asic_type) { | 7498 | switch (adev->asic_type) { |
| 7321 | case CHIP_SIENNA_CICHLID: | 7499 | case CHIP_SIENNA_CICHLID: |
| 7322 | case CHIP_NAVY_FLOUNDER: | 7500 | case CHIP_NAVY_FLOUNDER: |
| 7501 | case CHIP_VANGOGH: | ||
| 7502 | case CHIP_DIMGREY_CAVEFISH: | ||
| 7323 | WREG32_SOC15(GC, 0, mmRLC_SAFE_MODE_Sienna_Cichlid, data); | 7503 | WREG32_SOC15(GC, 0, mmRLC_SAFE_MODE_Sienna_Cichlid, data); |
| 7324 | break; | 7504 | break; |
| 7325 | default: | 7505 | default: |
| @@ -7344,6 +7524,7 @@ static void gfx_v10_0_update_medium_grain_clock_gating(struct amdgpu_device *ade · 18 unmodified lines | |||
| 7344 | /* 1 - RLC_CGTT_MGCG_OVERRIDE */ | 7524 | /* 1 - RLC_CGTT_MGCG_OVERRIDE */ |
| 7345 | def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE); | 7525 | def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE); |
| 7346 | data &= ~(RLC_CGTT_MGCG_OVERRIDE__GRBM_CGTT_SCLK_OVERRIDE_MASK | | 7526 | data &= ~(RLC_CGTT_MGCG_OVERRIDE__GRBM_CGTT_SCLK_OVERRIDE_MASK | |
| 7527 | RLC_CGTT_MGCG_OVERRIDE__RLC_CGTT_SCLK_OVERRIDE_MASK | | ||
| 7347 | RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGCG_OVERRIDE_MASK | | 7528 | RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGCG_OVERRIDE_MASK | |
| 7348 | RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGLS_OVERRIDE_MASK | | 7529 | RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGLS_OVERRIDE_MASK | |
| 7349 | RLC_CGTT_MGCG_OVERRIDE__ENABLE_CGTS_LEGACY_MASK); | 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 | static int gfx_v10_0_update_gfx_clock_gating(struct amdgpu_device *adev, | 7700 | static int gfx_v10_0_update_gfx_clock_gating(struct amdgpu_device *adev, |
| 7484 | bool enable) | 7701 | bool enable) |
| 7485 | { | 7702 | { |
| 7486 | amdgpu_gfx_rlc_enter_safe_mode(adev); | 7703 | amdgpu_gfx_rlc_enter_safe_mode(adev); |
| 7487 | 7704 | ||
| 7488 | if (enable) { | 7705 | if (enable) { |
| 7706 | /* enable FGCG firstly*/ | ||
| 7707 | gfx_v10_0_update_fine_grain_clock_gating(adev, enable); | ||
| 7489 | /* CGCG/CGLS should be enabled after MGCG/MGLS | 7708 | /* CGCG/CGLS should be enabled after MGCG/MGLS |
| 7490 | * === MGCG + MGLS === | 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 | gfx_v10_0_update_3d_clock_gating(adev, enable); | 7722 | gfx_v10_0_update_3d_clock_gating(adev, enable); |
| 7504 | /* === MGCG + MGLS === */ | 7723 | /* === MGCG + MGLS === */ |
| 7505 | gfx_v10_0_update_medium_grain_clock_gating(adev, enable); | 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 | if (adev->cg_flags & | 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 | return gfx_v10_0_check_rlcg_range(adev, offset, NULL, 0); | 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 | static const struct amdgpu_rlc_funcs gfx_v10_0_rlc_funcs = { | 7809 | static const struct amdgpu_rlc_funcs gfx_v10_0_rlc_funcs = { |
| 7568 | .is_rlc_enabled = gfx_v10_0_is_rlc_enabled, | 7810 | .is_rlc_enabled = gfx_v10_0_is_rlc_enabled, |
| 7569 | .set_safe_mode = gfx_v10_0_set_safe_mode, | 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 | case CHIP_NAVI12: | 7851 | case CHIP_NAVI12: |
| 7610 | case CHIP_SIENNA_CICHLID: | 7852 | case CHIP_SIENNA_CICHLID: |
| 7611 | case CHIP_NAVY_FLOUNDER: | 7853 | case CHIP_NAVY_FLOUNDER: |
| 7854 | case CHIP_DIMGREY_CAVEFISH: | ||
| 7612 | amdgpu_gfx_off_ctrl(adev, enable); | 7855 | amdgpu_gfx_off_ctrl(adev, enable); |
| 7613 | break; | 7856 | break; |
| 7857 | case CHIP_VANGOGH: | ||
| 7858 | gfx_v10_cntl_pg(adev, enable); | ||
| 7859 | break; | ||
| 7614 | default: | 7860 | default: |
| 7615 | break; | 7861 | break; |
| 7616 | } | 7862 | } |
| @@ -7631,6 +7877,8 @@ static int gfx_v10_0_set_clockgating_state(void *handle, · 14 unmodified lines | |||
| 7631 | case CHIP_NAVI12: | 7877 | case CHIP_NAVI12: |
| 7632 | case CHIP_SIENNA_CICHLID: | 7878 | case CHIP_SIENNA_CICHLID: |
| 7633 | case CHIP_NAVY_FLOUNDER: | 7879 | case CHIP_NAVY_FLOUNDER: |
| 7880 | case CHIP_VANGOGH: | ||
| 7881 | case CHIP_DIMGREY_CAVEFISH: | ||
| 7634 | gfx_v10_0_update_gfx_clock_gating(adev, | 7882 | gfx_v10_0_update_gfx_clock_gating(adev, |
| 7635 | state == AMD_CG_STATE_GATE); | 7883 | state == AMD_CG_STATE_GATE); |
| 7636 | break; | 7884 | break; |
| @@ -7645,6 +7893,11 @@ static void gfx_v10_0_get_clockgating_state(void *handle, u32 *flags) · 8 unmodified lines | |||
| 7645 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 7893 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 7646 | int data; | 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 | /* AMD_CG_SUPPORT_GFX_MGCG */ | 7901 | /* AMD_CG_SUPPORT_GFX_MGCG */ |
| 7649 | data = RREG32_KIQ(SOC15_REG_OFFSET(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE)); | 7902 | data = RREG32_KIQ(SOC15_REG_OFFSET(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE)); |
| 7650 | if (!(data & RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGCG_OVERRIDE_MASK)) | 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 | case CHIP_NAVI14: | 8986 | case CHIP_NAVI14: |
| 8734 | case CHIP_SIENNA_CICHLID: | 8987 | case CHIP_SIENNA_CICHLID: |
| 8735 | case CHIP_NAVY_FLOUNDER: | 8988 | case CHIP_NAVY_FLOUNDER: |
| 8989 | case CHIP_VANGOGH: | ||
| 8990 | case CHIP_DIMGREY_CAVEFISH: | ||
| 8736 | adev->gfx.rlc.funcs = &gfx_v10_0_rlc_funcs; | 8991 | adev->gfx.rlc.funcs = &gfx_v10_0_rlc_funcs; |
| 8737 | break; | 8992 | break; |
| 8738 | case CHIP_NAVI12: | 8993 | case CHIP_NAVI12: |
| @@ -3064,7 +3064,8 @@ static int gfx_v6_0_early_init(void *handle) · 3063 unmodified lines | |||
| 3064 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 3064 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 3065 | 3065 | ||
| 3066 | adev->gfx.num_gfx_rings = GFX6_NUM_GFX_RINGS; | 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 | adev->gfx.funcs = &gfx_v6_0_gfx_funcs; | 3069 | adev->gfx.funcs = &gfx_v6_0_gfx_funcs; |
| 3069 | adev->gfx.rlc.funcs = &gfx_v6_0_rlc_funcs; | 3070 | adev->gfx.rlc.funcs = &gfx_v6_0_rlc_funcs; |
| 3070 | gfx_v6_0_set_ring_funcs(adev); | 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 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 4238 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 4239 | 4239 | ||
| 4240 | adev->gfx.num_gfx_rings = GFX7_NUM_GFX_RINGS; | 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 | adev->gfx.funcs = &gfx_v7_0_gfx_funcs; | 4243 | adev->gfx.funcs = &gfx_v7_0_gfx_funcs; |
| 4243 | adev->gfx.rlc.funcs = &gfx_v7_0_rlc_funcs; | 4244 | adev->gfx.rlc.funcs = &gfx_v7_0_rlc_funcs; |
| 4244 | gfx_v7_0_set_ring_funcs(adev); | 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 | static void gfx_v8_0_ring_emit_ce_meta(struct amdgpu_ring *ring); | 729 | static void gfx_v8_0_ring_emit_ce_meta(struct amdgpu_ring *ring); |
| 730 | static void gfx_v8_0_ring_emit_de_meta(struct amdgpu_ring *ring); | 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 | static void gfx_v8_0_init_golden_registers(struct amdgpu_device *adev) | 735 | static void gfx_v8_0_init_golden_registers(struct amdgpu_device *adev) |
| 733 | { | 736 | { |
| 737 | uint32_t data; | ||
| 738 | |||
| 734 | switch (adev->asic_type) { | 739 | switch (adev->asic_type) { |
| 735 | case CHIP_TOPAZ: | 740 | case CHIP_TOPAZ: |
| 736 | amdgpu_device_program_register_sequence(adev, | 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 | amdgpu_device_program_register_sequence(adev, | 795 | amdgpu_device_program_register_sequence(adev, |
| 791 | polaris10_golden_common_all, | 796 | polaris10_golden_common_all, |
| 792 | ARRAY_SIZE(polaris10_golden_common_all)); | 797 | ARRAY_SIZE(polaris10_golden_common_all)); |
| 793 | WREG32_SMC(ixCG_ACLK_CNTL, 0x0000001C); | 798 | data = RREG32_SMC(ixCG_ACLK_CNTL); |
| 794 | if (adev->pdev->revision == 0xc7 && | 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 | ((adev->pdev->subsystem_device == 0xb37 && adev->pdev->subsystem_vendor == 0x1002) || | 803 | ((adev->pdev->subsystem_device == 0xb37 && adev->pdev->subsystem_vendor == 0x1002) || |
| 796 | (adev->pdev->subsystem_device == 0x4a8 && adev->pdev->subsystem_vendor == 0x1043) || | 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 | amdgpu_atombios_i2c_channel_trans(adev, 0x10, 0x96, 0x1E, 0xDD); | 806 | amdgpu_atombios_i2c_channel_trans(adev, 0x10, 0x96, 0x1E, 0xDD); |
| 799 | amdgpu_atombios_i2c_channel_trans(adev, 0x10, 0x96, 0x1F, 0xD0); | 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 | gfx_v8_0_cp_compute_enable(adev, false); | 5066 | gfx_v8_0_cp_compute_enable(adev, false); |
| 5059 | } | 5067 | } |
| 5060 | 5068 | ||
| 5061 | return 0; | 5069 | return 0; |
| 5062 | } | 5070 | } |
| 5063 | 5071 | ||
| 5064 | static int gfx_v8_0_soft_reset(void *handle) | 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 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 5303 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 5296 | 5304 | ||
| 5297 | adev->gfx.num_gfx_rings = GFX8_NUM_GFX_RINGS; | 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 | adev->gfx.funcs = &gfx_v8_0_gfx_funcs; | 5308 | adev->gfx.funcs = &gfx_v8_0_gfx_funcs; |
| 5300 | gfx_v8_0_set_ring_funcs(adev); | 5309 | gfx_v8_0_set_ring_funcs(adev); |
| 5301 | gfx_v8_0_set_irq_funcs(adev); | 5310 | gfx_v8_0_set_irq_funcs(adev); |
| @@ -117,6 +117,13 @@ MODULE_FIRMWARE("amdgpu/renoir_mec.bin"); · 116 unmodified lines | |||
| 117 | MODULE_FIRMWARE("amdgpu/renoir_mec2.bin"); | 117 | MODULE_FIRMWARE("amdgpu/renoir_mec2.bin"); |
| 118 | MODULE_FIRMWARE("amdgpu/renoir_rlc.bin"); | 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 | #define mmTCP_CHAN_STEER_0_ARCT 0x0b03 | 127 | #define mmTCP_CHAN_STEER_0_ARCT 0x0b03 |
| 121 | #define mmTCP_CHAN_STEER_0_ARCT_BASE_IDX 0 | 128 | #define mmTCP_CHAN_STEER_0_ARCT_BASE_IDX 0 |
| 122 | #define mmTCP_CHAN_STEER_1_ARCT 0x0b04 | 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 | static void gfx_v9_0_set_gds_init(struct amdgpu_device *adev); | 794 | static void gfx_v9_0_set_gds_init(struct amdgpu_device *adev); |
| 788 | static void gfx_v9_0_set_rlc_funcs(struct amdgpu_device *adev); | 795 | static void gfx_v9_0_set_rlc_funcs(struct amdgpu_device *adev); |
| 789 | static int gfx_v9_0_get_cu_info(struct amdgpu_device *adev, | 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 | static uint64_t gfx_v9_0_get_gpu_clock_counter(struct amdgpu_device *adev); | 798 | static uint64_t gfx_v9_0_get_gpu_clock_counter(struct amdgpu_device *adev); |
| 792 | static void gfx_v9_0_ring_emit_de_meta(struct amdgpu_ring *ring); | 799 | static void gfx_v9_0_ring_emit_de_meta(struct amdgpu_ring *ring); |
| 793 | static u64 gfx_v9_0_ring_get_rptr_compute(struct amdgpu_ring *ring); | 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 | chip_name = "arcturus"; | 1637 | chip_name = "arcturus"; |
| 1631 | break; | 1638 | break; |
| 1632 | case CHIP_RENOIR: | 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 | break; | 1644 | break; |
| 1635 | default: | 1645 | default: |
| 1636 | BUG(); | 1646 | BUG(); |
| @@ -4623,7 +4633,8 @@ static int gfx_v9_0_early_init(void *handle) · 2986 unmodified lines | |||
| 4623 | adev->gfx.num_gfx_rings = 0; | 4633 | adev->gfx.num_gfx_rings = 0; |
| 4624 | else | 4634 | else |
| 4625 | adev->gfx.num_gfx_rings = GFX9_NUM_GFX_RINGS; | 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 | gfx_v9_0_set_kiq_pm4_funcs(adev); | 4638 | gfx_v9_0_set_kiq_pm4_funcs(adev); |
| 4628 | gfx_v9_0_set_ring_funcs(adev); | 4639 | gfx_v9_0_set_ring_funcs(adev); |
| 4629 | gfx_v9_0_set_irq_funcs(adev); | 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 | if (ring->use_doorbell) { | 5179 | if (ring->use_doorbell) { |
| 5169 | /* XXX check if swapping is necessary on BE */ | 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 | WDOORBELL64(ring->doorbell_index, ring->wptr); | 5182 | WDOORBELL64(ring->doorbell_index, ring->wptr); |
| 5172 | } else { | 5183 | } else { |
| 5173 | WREG32_SOC15(GC, 0, mmCP_RB0_WPTR, lower_32_bits(ring->wptr)); | 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 | /* XXX check if swapping is necessary on BE */ | 5365 | /* XXX check if swapping is necessary on BE */ |
| 5355 | if (ring->use_doorbell) { | 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 | WDOORBELL64(ring->doorbell_index, ring->wptr); | 5368 | WDOORBELL64(ring->doorbell_index, ring->wptr); |
| 5358 | } else{ | 5369 | } else{ |
| 5359 | BUG(); /* only DOORBELL method supported on gfx9 now */ | 5370 | BUG(); /* only DOORBELL method supported on gfx9 now */ |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | |||
| 22 | */ | 22 | */ |
| 23 | #include "amdgpu.h" | 23 | #include "amdgpu.h" |
| 24 | #include "gfxhub_v1_0.h" | 24 | #include "gfxhub_v1_0.h" |
| 25 | #include "gfxhub_v1_1.h" | ||
| 25 | 26 | ||
| 26 | #include "gc/gc_9_0_offset.h" | 27 | #include "gc/gc_9_0_offset.h" |
| 27 | #include "gc/gc_9_0_sh_mask.h" | 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 | .gart_disable = gfxhub_v1_0_gart_disable, | 413 | .gart_disable = gfxhub_v1_0_gart_disable, |
| 413 | .set_fault_enable_default = gfxhub_v1_0_set_fault_enable_default, | 414 | .set_fault_enable_default = gfxhub_v1_0_set_fault_enable_default, |
| 414 | .init = gfxhub_v1_0_init, | 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 | #include "amdgpu.h" | 23 | #include "amdgpu.h" |
| 24 | #include "gfxhub_v1_0.h" | ||
| 25 | #include "gfxhub_v1_1.h" | 24 | #include "gfxhub_v1_1.h" |
| 26 | 25 | ||
| 27 | #include "gc/gc_9_2_1_offset.h" | 26 | #include "gc/gc_9_2_1_offset.h" |
| @@ -29,7 +28,7 @@ · 1 unmodified line | |||
| 29 | 28 | ||
| 30 | #include "soc15_common.h" | 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 | u32 xgmi_lfb_cntl = RREG32_SOC15(GC, 0, mmMC_VM_XGMI_LFB_CNTL); | 33 | u32 xgmi_lfb_cntl = RREG32_SOC15(GC, 0, mmMC_VM_XGMI_LFB_CNTL); |
| 35 | u32 max_region = | 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 | return 0; | 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 | #ifndef __GFXHUB_V1_1_H__ | 24 | #ifndef __GFXHUB_V1_1_H__ |
| 25 | #define __GFXHUB_V1_1_H__ | 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 | #endif | 29 | #endif |
| @@ -46,6 +46,7 @@ · 45 unmodified lines | |||
| 46 | #include "gfxhub_v2_0.h" | 46 | #include "gfxhub_v2_0.h" |
| 47 | #include "gfxhub_v2_1.h" | 47 | #include "gfxhub_v2_1.h" |
| 48 | #include "mmhub_v2_0.h" | 48 | #include "mmhub_v2_0.h" |
| 49 | #include "mmhub_v2_3.h" | ||
| 49 | #include "athub_v2_0.h" | 50 | #include "athub_v2_0.h" |
| 50 | #include "athub_v2_1.h" | 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 | * be updated to avoid reading an incorrect value due to | 107 | * be updated to avoid reading an incorrect value due to |
| 107 | * the new fast GRBM interface. | 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 | RREG32(hub->vm_l2_pro_fault_status); | 112 | RREG32(hub->vm_l2_pro_fault_status); |
| 111 | 113 | ||
| 112 | status = RREG32(hub->vm_l2_pro_fault_status); | 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 | .process = amdgpu_umc_process_ecc_irq, | 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 | adev->gmc.vm_fault.num_types = 1; | 152 | adev->gmc.vm_fault.num_types = 1; |
| 151 | adev->gmc.vm_fault.funcs = &gmc_v10_0_irq_funcs; | 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 | * Issue a dummy read to wait for the ACK register to be cleared | 233 | * Issue a dummy read to wait for the ACK register to be cleared |
| 232 | * to avoid a false ACK due to the new fast GRBM interface. | 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 | RREG32_NO_KIQ(hub->vm_inv_eng0_req + hub->eng_distance * eng); | 238 | RREG32_NO_KIQ(hub->vm_inv_eng0_req + hub->eng_distance * eng); |
| 236 | 239 | ||
| 237 | /* Wait for ACK with a delay.*/ | 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 | * PTE format on NAVI 10: | 487 | * PTE format on NAVI 10: |
| 485 | * 63:59 reserved | 488 | * 63:59 reserved |
| 486 | * 58:57 reserved | 489 | * 58 reserved and for sienna_cichlid is used for MALL noalloc |
| 490 | * 57 reserved | ||
| 487 | * 56 F | 491 | * 56 F |
| 488 | * 55 L | 492 | * 55 L |
| 489 | * 54 reserved | 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 | static void gmc_v10_0_set_mmhub_funcs(struct amdgpu_device *adev) | 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 | static void gmc_v10_0_set_gfxhub_funcs(struct amdgpu_device *adev) | 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 | switch (adev->asic_type) { | 650 | switch (adev->asic_type) { |
| 640 | case CHIP_SIENNA_CICHLID: | 651 | case CHIP_SIENNA_CICHLID: |
| 641 | case CHIP_NAVY_FLOUNDER: | 652 | case CHIP_NAVY_FLOUNDER: |
| 653 | case CHIP_VANGOGH: | ||
| 654 | case CHIP_DIMGREY_CAVEFISH: | ||
| 642 | adev->gfxhub.funcs = &gfxhub_v2_1_funcs; | 655 | adev->gfxhub.funcs = &gfxhub_v2_1_funcs; |
| 643 | break; | 656 | break; |
| 644 | default: | 657 | default: |
| @@ -733,6 +746,13 @@ static int gmc_v10_0_mc_init(struct amdgpu_device *adev) · 88 unmodified lines | |||
| 733 | adev->gmc.aper_base = pci_resource_start(adev->pdev, 0); | 746 | adev->gmc.aper_base = pci_resource_start(adev->pdev, 0); |
| 734 | adev->gmc.aper_size = pci_resource_len(adev->pdev, 0); | 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 | /* In case the PCI BAR is larger than the actual amount of vram */ | 756 | /* In case the PCI BAR is larger than the actual amount of vram */ |
| 737 | adev->gmc.visible_vram_size = adev->gmc.aper_size; | 757 | adev->gmc.visible_vram_size = adev->gmc.aper_size; |
| 738 | if (adev->gmc.visible_vram_size > adev->gmc.real_vram_size) | 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 | case CHIP_NAVI12: | 766 | case CHIP_NAVI12: |
| 747 | case CHIP_SIENNA_CICHLID: | 767 | case CHIP_SIENNA_CICHLID: |
| 748 | case CHIP_NAVY_FLOUNDER: | 768 | case CHIP_NAVY_FLOUNDER: |
| 769 | case CHIP_VANGOGH: | ||
| 770 | case CHIP_DIMGREY_CAVEFISH: | ||
| 749 | default: | 771 | default: |
| 750 | adev->gmc.gart_size = 512ULL << 20; | 772 | adev->gmc.gart_size = 512ULL << 20; |
| 751 | break; | 773 | break; |
| @@ -790,7 +812,10 @@ static int gmc_v10_0_sw_init(void *handle) · 38 unmodified lines | |||
| 790 | 812 | ||
| 791 | spin_lock_init(&adev->gmc.invalidate_lock); | 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 | adev->gmc.vram_type = AMDGPU_VRAM_TYPE_GDDR6; | 819 | adev->gmc.vram_type = AMDGPU_VRAM_TYPE_GDDR6; |
| 795 | adev->gmc.vram_width = 1 * 128; /* numchan * chansize */ | 820 | adev->gmc.vram_width = 1 * 128; /* numchan * chansize */ |
| 796 | } else { | 821 | } else { |
| @@ -808,6 +833,8 @@ static int gmc_v10_0_sw_init(void *handle) · 11 unmodified lines | |||
| 808 | case CHIP_NAVI12: | 833 | case CHIP_NAVI12: |
| 809 | case CHIP_SIENNA_CICHLID: | 834 | case CHIP_SIENNA_CICHLID: |
| 810 | case CHIP_NAVY_FLOUNDER: | 835 | case CHIP_NAVY_FLOUNDER: |
| 836 | case CHIP_VANGOGH: | ||
| 837 | case CHIP_DIMGREY_CAVEFISH: | ||
| 811 | adev->num_vmhubs = 2; | 838 | adev->num_vmhubs = 2; |
| 812 | /* | 839 | /* |
| 813 | * To fulfill 4-level page support, | 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 | case CHIP_NAVI12: | 948 | case CHIP_NAVI12: |
| 922 | case CHIP_SIENNA_CICHLID: | 949 | case CHIP_SIENNA_CICHLID: |
| 923 | case CHIP_NAVY_FLOUNDER: | 950 | case CHIP_NAVY_FLOUNDER: |
| 951 | case CHIP_VANGOGH: | ||
| 952 | case CHIP_DIMGREY_CAVEFISH: | ||
| 924 | break; | 953 | break; |
| 925 | default: | 954 | default: |
| 926 | break; | 955 | break; |
| @@ -1081,8 +1110,8 @@ static int gmc_v10_0_set_clockgating_state(void *handle, · 154 unmodified lines | |||
| 1081 | if (r) | 1110 | if (r) |
| 1082 | return r; | 1111 | return r; |
| 1083 | 1112 | ||
| 1084 | if (adev->asic_type == CHIP_SIENNA_CICHLID || | 1113 | if (adev->asic_type >= CHIP_SIENNA_CICHLID && |
| 1085 | adev->asic_type == CHIP_NAVY_FLOUNDER) | 1114 | adev->asic_type <= CHIP_DIMGREY_CAVEFISH) |
| 1086 | return athub_v2_1_set_clockgating(adev, state); | 1115 | return athub_v2_1_set_clockgating(adev, state); |
| 1087 | else | 1116 | else |
| 1088 | return athub_v2_0_set_clockgating(adev, state); | 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 | adev->mmhub.funcs->get_clockgating(adev, flags); | 1124 | adev->mmhub.funcs->get_clockgating(adev, flags); |
| 1096 | 1125 | ||
| 1097 | if (adev->asic_type == CHIP_SIENNA_CICHLID || | 1126 | if (adev->asic_type >= CHIP_SIENNA_CICHLID && |
| 1098 | adev->asic_type == CHIP_NAVY_FLOUNDER) | 1127 | adev->asic_type <= CHIP_DIMGREY_CAVEFISH) |
| 1099 | athub_v2_1_get_clockgating(adev, flags); | 1128 | athub_v2_1_get_clockgating(adev, flags); |
| 1100 | else | 1129 | else |
| 1101 | athub_v2_0_get_clockgating(adev, flags); | 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 | chip_name = "tonga"; | 230 | chip_name = "tonga"; |
| 231 | break; | 231 | break; |
| 232 | case CHIP_POLARIS11: | 232 | case CHIP_POLARIS11: |
| 233 | if (((adev->pdev->device == 0x67ef) && | 233 | if (ASICID_IS_P21(adev->pdev->device, adev->pdev->revision) || |
| 234 | ((adev->pdev->revision == 0xe0) || | 234 | ASICID_IS_P31(adev->pdev->device, adev->pdev->revision)) |
| 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)) | ||
| 243 | chip_name = "polaris11_k"; | 235 | chip_name = "polaris11_k"; |
| 244 | else | 236 | else |
| 245 | chip_name = "polaris11"; | 237 | chip_name = "polaris11"; |
| 246 | break; | 238 | break; |
| 247 | case CHIP_POLARIS10: | 239 | case CHIP_POLARIS10: |
| 248 | if ((adev->pdev->device == 0x67df) && | 240 | if (ASICID_IS_P30(adev->pdev->device, adev->pdev->revision)) |
| 249 | ((adev->pdev->revision == 0xe1) || | ||
| 250 | (adev->pdev->revision == 0xf7))) | ||
| 251 | chip_name = "polaris10_k"; | 241 | chip_name = "polaris10_k"; |
| 252 | else | 242 | else |
| 253 | chip_name = "polaris10"; | 243 | chip_name = "polaris10"; |
| 254 | break; | 244 | break; |
| 255 | case CHIP_POLARIS12: | 245 | case CHIP_POLARIS12: |
| 256 | if (((adev->pdev->device == 0x6987) && | 246 | if (ASICID_IS_P23(adev->pdev->device, adev->pdev->revision)) |
| 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)))) | ||
| 263 | chip_name = "polaris12_k"; | 247 | chip_name = "polaris12_k"; |
| 264 | else | 248 | else |
| 265 | chip_name = "polaris12"; | 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 | static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev, | 512 | static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev, |
| 513 | struct amdgpu_irq_src *source, | 513 | struct amdgpu_irq_src *source, |
| 514 | struct amdgpu_iv_entry *entry) | 514 | struct amdgpu_iv_entry *entry) |
| 515 | { | 515 | { |
| 516 | struct amdgpu_vmhub *hub; | ||
| 517 | bool retry_fault = !!(entry->src_data[1] & 0x80); | 516 | bool retry_fault = !!(entry->src_data[1] & 0x80); |
| 518 | uint32_t status = 0, cid = 0, rw = 0; | 517 | uint32_t status = 0, cid = 0, rw = 0; |
| 519 | u64 addr; | 518 | struct amdgpu_task_info task_info; |
| 520 | char hub_name[10]; | 519 | struct amdgpu_vmhub *hub; |
| 521 | const char *mmhub_cid; | 520 | const char *mmhub_cid; |
| 521 | const char *hub_name; | ||
| 522 | u64 addr; | ||
| 522 | 523 | ||
| 523 | addr = (u64)entry->src_data[0] << 12; | 524 | addr = (u64)entry->src_data[0] << 12; |
| 524 | addr |= ((u64)entry->src_data[1] & 0xf) << 44; | 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 | entry->timestamp)) | 528 | entry->timestamp)) |
| 528 | return 1; /* This also prevents sending it to KFD */ | 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 | if (entry->client_id == SOC15_IH_CLIENTID_VMC) { | 539 | if (entry->client_id == SOC15_IH_CLIENTID_VMC) { |
| 531 | snprintf(hub_name, sizeof(hub_name), "mmhub0"); | 540 | hub_name = "mmhub0"; |
| 532 | hub = &adev->vmhub[AMDGPU_MMHUB_0]; | 541 | hub = &adev->vmhub[AMDGPU_MMHUB_0]; |
| 533 | } else if (entry->client_id == SOC15_IH_CLIENTID_VMC1) { | 542 | } else if (entry->client_id == SOC15_IH_CLIENTID_VMC1) { |
| 534 | snprintf(hub_name, sizeof(hub_name), "mmhub1"); | 543 | hub_name = "mmhub1"; |
| 535 | hub = &adev->vmhub[AMDGPU_MMHUB_1]; | 544 | hub = &adev->vmhub[AMDGPU_MMHUB_1]; |
| 536 | } else { | 545 | } else { |
| 537 | snprintf(hub_name, sizeof(hub_name), "gfxhub0"); | 546 | hub_name = "gfxhub0"; |
| 538 | hub = &adev->vmhub[AMDGPU_GFXHUB_0]; | 547 | hub = &adev->vmhub[AMDGPU_GFXHUB_0]; |
| 539 | } | 548 | } |
| 540 | 549 | ||
| 541 | /* If it's the first fault for this address, process it normally */ | 550 | memset(&task_info, 0, sizeof(struct amdgpu_task_info)); |
| 542 | if (retry_fault && !in_interrupt() && | 551 | amdgpu_vm_get_task_info(adev, entry->pasid, &task_info); |
| 543 | amdgpu_vm_handle_fault(adev, entry->pasid, addr)) | ||
| 544 | return 1; /* This also prevents sending it to KFD */ | ||
| 545 | 552 | ||
| 546 | if (!amdgpu_sriov_vf(adev)) { | 553 | dev_err(adev->dev, |
| 547 | /* | 554 | "[%s] %s page fault (src_id:%u ring:%u vmid:%u " |
| 548 | * Issue a dummy read to wait for the status register to | 555 | "pasid:%u, for process %s pid %d thread %s pid %d)\n", |
| 549 | * be updated to avoid reading an incorrect value due to | 556 | hub_name, retry_fault ? "retry" : "no-retry", |
| 550 | * the new fast GRBM interface. | 557 | entry->src_id, entry->ring_id, entry->vmid, |
| 551 | */ | 558 | entry->pasid, task_info.process_name, task_info.tgid, |
| 552 | if (entry->vmid_src == AMDGPU_GFXHUB_0) | 559 | task_info.task_name, task_info.pid); |
| 553 | RREG32(hub->vm_l2_pro_fault_status); | 560 | dev_err(adev->dev, " in page starting at address 0x%016llx from client %d\n", |
| 554 | 561 | addr, entry->client_id); | |
| 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 | } | ||
| 562 | 562 | ||
| 563 | if (printk_ratelimit()) { | 563 | if (amdgpu_sriov_vf(adev)) |
| 564 | struct amdgpu_task_info task_info; | 564 | return 0; |
| 565 | 565 | ||
| 566 | memset(&task_info, 0, sizeof(struct amdgpu_task_info)); | 566 | /* |
| 567 | amdgpu_vm_get_task_info(adev, entry->pasid, &task_info); | 567 | * Issue a dummy read to wait for the status register to |
| 568 | 568 | * be updated to avoid reading an incorrect value due to | |
| 569 | dev_err(adev->dev, | 569 | * the new fast GRBM interface. |
| 570 | "[%s] %s page fault (src_id:%u ring:%u vmid:%u " | 570 | */ |
| 571 | "pasid:%u, for process %s pid %d thread %s pid %d)\n", | 571 | if (entry->vmid_src == AMDGPU_GFXHUB_0) |
| 572 | hub_name, retry_fault ? "retry" : "no-retry", | 572 | RREG32(hub->vm_l2_pro_fault_status); |
| 573 | entry->src_id, entry->ring_id, entry->vmid, | 573 | |
| 574 | entry->pasid, task_info.process_name, task_info.tgid, | 574 | status = RREG32(hub->vm_l2_pro_fault_status); |
| 575 | task_info.task_name, task_info.pid); | 575 | cid = REG_GET_FIELD(status, VM_L2_PROTECTION_FAULT_STATUS, CID); |
| 576 | dev_err(adev->dev, " in page starting at address 0x%016llx from client %d\n", | 576 | rw = REG_GET_FIELD(status, VM_L2_PROTECTION_FAULT_STATUS, RW); |
| 577 | addr, entry->client_id); | 577 | WREG32_P(hub->vm_l2_pro_fault_cntl, 1, ~1); |
| 578 | if (!amdgpu_sriov_vf(adev)) { | 578 | |
| 579 | dev_err(adev->dev, | 579 | |
| 580 | "VM_L2_PROTECTION_FAULT_STATUS:0x%08X\n", | 580 | dev_err(adev->dev, |
| 581 | status); | 581 | "VM_L2_PROTECTION_FAULT_STATUS:0x%08X\n", |
| 582 | if (hub == &adev->vmhub[AMDGPU_GFXHUB_0]) { | 582 | status); |
| 583 | dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n", | 583 | if (hub == &adev->vmhub[AMDGPU_GFXHUB_0]) { |
| 584 | cid >= ARRAY_SIZE(gfxhub_client_ids) ? "unknown" : gfxhub_client_ids[cid], | 584 | dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n", |
| 585 | cid); | 585 | cid >= ARRAY_SIZE(gfxhub_client_ids) ? "unknown" : |
| 586 | } else { | 586 | gfxhub_client_ids[cid], |
| 587 | switch (adev->asic_type) { | 587 | cid); |
| 588 | case CHIP_VEGA10: | 588 | } else { |
| 589 | mmhub_cid = mmhub_client_ids_vega10[cid][rw]; | 589 | switch (adev->asic_type) { |
| 590 | break; | 590 | case CHIP_VEGA10: |
| 591 | case CHIP_VEGA12: | 591 | mmhub_cid = mmhub_client_ids_vega10[cid][rw]; |
| 592 | mmhub_cid = mmhub_client_ids_vega12[cid][rw]; | 592 | break; |
| 593 | break; | 593 | case CHIP_VEGA12: |
| 594 | case CHIP_VEGA20: | 594 | mmhub_cid = mmhub_client_ids_vega12[cid][rw]; |
| 595 | mmhub_cid = mmhub_client_ids_vega20[cid][rw]; | 595 | break; |
| 596 | break; | 596 | case CHIP_VEGA20: |
| 597 | case CHIP_ARCTURUS: | 597 | mmhub_cid = mmhub_client_ids_vega20[cid][rw]; |
| 598 | mmhub_cid = mmhub_client_ids_arcturus[cid][rw]; | 598 | break; |
| 599 | break; | 599 | case CHIP_ARCTURUS: |
| 600 | case CHIP_RAVEN: | 600 | mmhub_cid = mmhub_client_ids_arcturus[cid][rw]; |
| 601 | mmhub_cid = mmhub_client_ids_raven[cid][rw]; | 601 | break; |
| 602 | break; | 602 | case CHIP_RAVEN: |
| 603 | case CHIP_RENOIR: | 603 | mmhub_cid = mmhub_client_ids_raven[cid][rw]; |
| 604 | mmhub_cid = mmhub_client_ids_renoir[cid][rw]; | 604 | break; |
| 605 | break; | 605 | case CHIP_RENOIR: |
| 606 | default: | 606 | mmhub_cid = mmhub_client_ids_renoir[cid][rw]; |
| 607 | mmhub_cid = NULL; | 607 | break; |
| 608 | break; | 608 | default: |
| 609 | } | 609 | mmhub_cid = NULL; |
| 610 | dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n", | 610 | break; |
| 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); | ||
| 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 | return 0; | 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 | static void gmc_v9_0_set_gfxhub_funcs(struct amdgpu_device *adev) | 1166 | static void gmc_v9_0_set_gfxhub_funcs(struct amdgpu_device *adev) |
| 1168 | { | 1167 | { |
| 1169 | switch (adev->asic_type) { | 1168 | adev->gfxhub.funcs = &gfxhub_v1_0_funcs; |
| 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 | } | ||
| 1178 | } | 1169 | } |
| 1179 | 1170 | ||
| 1180 | static int gmc_v9_0_early_init(void *handle) | 1171 | static int gmc_v9_0_early_init(void *handle) |
| @@ -32,19 +32,19 @@ · 31 unmodified lines | |||
| 32 | #include "vcn/vcn_2_0_0_sh_mask.h" | 32 | #include "vcn/vcn_2_0_0_sh_mask.h" |
| 33 | #include "ivsrcid/vcn/irqsrcs_vcn_2_0.h" | 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 | #define mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET 0x4029 | 36 | #define mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET 0x4029 |
| 37 | #define mmUVD_JPEG_GPCOM_DATA0_INTERNAL_OFFSET 0x402a | 37 | #define mmUVD_JPEG_GPCOM_DATA0_INTERNAL_OFFSET 0x402a |
| 38 | #define mmUVD_JPEG_GPCOM_DATA1_INTERNAL_OFFSET 0x402b | 38 | #define mmUVD_JPEG_GPCOM_DATA1_INTERNAL_OFFSET 0x402b |
| 39 | #define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40ea | 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 | #define mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET 0x40cf | 41 | #define mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET 0x40cf |
| 42 | #define mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET 0x40d1 | 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 | #define mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40e9 | 44 | #define mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 0x40e9 |
| 45 | #define mmUVD_JRBC_IB_SIZE_INTERNAL_OFFSET 0x4082 | 45 | #define mmUVD_JRBC_IB_SIZE_INTERNAL_OFFSET 0x4082 |
| 46 | #define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW_INTERNAL_OFFSET 0x40ec | 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 | #define mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET 0x4085 | 48 | #define mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET 0x4085 |
| 49 | #define mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET 0x4084 | 49 | #define mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET 0x4084 |
| 50 | #define mmUVD_JRBC_STATUS_INTERNAL_OFFSET 0x4089 | 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 | return 0; | 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 | if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) { | 252 | if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) { |
| 253 | uint32_t data; | 253 | uint32_t data; |
| @@ -274,7 +274,7 @@ static int jpeg_v2_0_enable_power_gating(struct amdgpu_device* adev) · 20 unmodified lines | |||
| 274 | return 0; | 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 | uint32_t data; | 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 | WREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE, data); | 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 | uint32_t data; | 302 | uint32_t data; |
| 303 | 303 | ||
| @@ -247,7 +247,7 @@ static int jpeg_v2_5_resume(void *handle) · 246 unmodified lines | |||
| 247 | return r; | 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 | uint32_t data; | 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 | WREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL, data); | 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 | uint32_t data; | 281 | uint32_t data; |
| 282 | 282 | ||
| @@ -213,7 +213,7 @@ static int jpeg_v3_0_resume(void *handle) · 212 unmodified lines | |||
| 213 | return r; | 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 | uint32_t data = 0; | 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 | WREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL, data); | 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 | uint32_t data = 0; | 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 | return 0; | 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 | /* enable anti hang mechanism */ | 291 | /* enable anti hang mechanism */ |
| 292 | WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_POWER_STATUS), | 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 | struct amdgpu_device *adev = ring->adev; | 46 | struct amdgpu_device *adev = ring->adev; |
| 47 | 47 | ||
| 48 | if (ring->use_doorbell) { | 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 | ring->wptr); | 50 | ring->wptr); |
| 51 | WDOORBELL64(ring->doorbell_index, ring->wptr); | 51 | WDOORBELL64(ring->doorbell_index, ring->wptr); |
| 52 | } else { | 52 | } else { |
| @@ -409,7 +409,7 @@ static void mmhub_v1_0_set_fault_enable_default(struct amdgpu_device *adev, bool · 408 unmodified lines | |||
| 409 | CRASH_ON_NO_RETRY_FAULT, 1); | 409 | CRASH_ON_NO_RETRY_FAULT, 1); |
| 410 | tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL, | 410 | tmp = REG_SET_FIELD(tmp, VM_L2_PROTECTION_FAULT_CNTL, |
| 411 | CRASH_ON_RETRY_FAULT, 1); | 411 | CRASH_ON_RETRY_FAULT, 1); |
| 412 | } | 412 | } |
| 413 | 413 | ||
| 414 | WREG32_SOC15(MMHUB, 0, mmVM_L2_PROTECTION_FAULT_CNTL, tmp); | 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 | uint32_t sec_cnt, ded_cnt; | 712 | uint32_t sec_cnt, ded_cnt; |
| 713 | 713 | ||
| 714 | for (i = 0; i < ARRAY_SIZE(mmhub_v1_0_ras_fields); i++) { | 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 | continue; | 716 | continue; |
| 717 | 717 | ||
| 718 | sec_cnt = (value & | 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 | switch (adev->asic_type) { | 543 | switch (adev->asic_type) { |
| 544 | case CHIP_SIENNA_CICHLID: | 544 | case CHIP_SIENNA_CICHLID: |
| 545 | case CHIP_NAVY_FLOUNDER: | 545 | case CHIP_NAVY_FLOUNDER: |
| 546 | case CHIP_DIMGREY_CAVEFISH: | ||
| 546 | def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid); | 547 | def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid); |
| 547 | def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid); | 548 | def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid); |
| 548 | break; | 549 | break; |
| @@ -576,6 +577,7 @@ static void mmhub_v2_0_update_medium_grain_clock_gating(struct amdgpu_device *ad · 27 unmodified lines | |||
| 576 | switch (adev->asic_type) { | 577 | switch (adev->asic_type) { |
| 577 | case CHIP_SIENNA_CICHLID: | 578 | case CHIP_SIENNA_CICHLID: |
| 578 | case CHIP_NAVY_FLOUNDER: | 579 | case CHIP_NAVY_FLOUNDER: |
| 580 | case CHIP_DIMGREY_CAVEFISH: | ||
| 579 | if (def != data) | 581 | if (def != data) |
| 580 | WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data); | 582 | WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data); |
| 581 | if (def1 != data1) | 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 | switch (adev->asic_type) { | 600 | switch (adev->asic_type) { |
| 599 | case CHIP_SIENNA_CICHLID: | 601 | case CHIP_SIENNA_CICHLID: |
| 600 | case CHIP_NAVY_FLOUNDER: | 602 | case CHIP_NAVY_FLOUNDER: |
| 603 | case CHIP_DIMGREY_CAVEFISH: | ||
| 601 | def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid); | 604 | def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid); |
| 602 | break; | 605 | break; |
| 603 | default: | 606 | default: |
| @@ -614,6 +617,7 @@ static void mmhub_v2_0_update_medium_grain_light_sleep(struct amdgpu_device *ade · 10 unmodified lines | |||
| 614 | switch (adev->asic_type) { | 617 | switch (adev->asic_type) { |
| 615 | case CHIP_SIENNA_CICHLID: | 618 | case CHIP_SIENNA_CICHLID: |
| 616 | case CHIP_NAVY_FLOUNDER: | 619 | case CHIP_NAVY_FLOUNDER: |
| 620 | case CHIP_DIMGREY_CAVEFISH: | ||
| 617 | WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data); | 621 | WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data); |
| 618 | break; | 622 | break; |
| 619 | default: | 623 | default: |
| @@ -635,6 +639,7 @@ static int mmhub_v2_0_set_clockgating(struct amdgpu_device *adev, · 15 unmodified lines | |||
| 635 | case CHIP_NAVI12: | 639 | case CHIP_NAVI12: |
| 636 | case CHIP_SIENNA_CICHLID: | 640 | case CHIP_SIENNA_CICHLID: |
| 637 | case CHIP_NAVY_FLOUNDER: | 641 | case CHIP_NAVY_FLOUNDER: |
| 642 | case CHIP_DIMGREY_CAVEFISH: | ||
| 638 | mmhub_v2_0_update_medium_grain_clock_gating(adev, | 643 | mmhub_v2_0_update_medium_grain_clock_gating(adev, |
| 639 | state == AMD_CG_STATE_GATE); | 644 | state == AMD_CG_STATE_GATE); |
| 640 | mmhub_v2_0_update_medium_grain_light_sleep(adev, | 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 | switch (adev->asic_type) { | 662 | switch (adev->asic_type) { |
| 658 | case CHIP_SIENNA_CICHLID: | 663 | case CHIP_SIENNA_CICHLID: |
| 659 | case CHIP_NAVY_FLOUNDER: | 664 | case CHIP_NAVY_FLOUNDER: |
| 665 | case CHIP_DIMGREY_CAVEFISH: | ||
| 660 | data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid); | 666 | data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid); |
| 661 | data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid); | 667 | data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid); |
| 662 | break; | 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 | switch (adev->asic_type) { | 314 | switch (adev->asic_type) { |
| 315 | case CHIP_SIENNA_CICHLID: | 315 | case CHIP_SIENNA_CICHLID: |
| 316 | case CHIP_NAVY_FLOUNDER: | 316 | case CHIP_NAVY_FLOUNDER: |
| 317 | case CHIP_VANGOGH: | ||
| 318 | case CHIP_DIMGREY_CAVEFISH: | ||
| 317 | ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN_Sienna_Cichlid); | 319 | ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN_Sienna_Cichlid); |
| 318 | ih_chicken = REG_SET_FIELD(ih_chicken, | 320 | ih_chicken = REG_SET_FIELD(ih_chicken, |
| 319 | IH_CHICKEN, MC_SPACE_GPA_ENABLE, 1); | 321 | IH_CHICKEN, MC_SPACE_GPA_ENABLE, 1); |
| @@ -660,8 +662,11 @@ static int navi10_ih_sw_init(void *handle) · 340 unmodified lines | |||
| 660 | /* use gpu virtual address for ih ring | 662 | /* use gpu virtual address for ih ring |
| 661 | * until ih_checken is programmed to allow | 663 | * until ih_checken is programmed to allow |
| 662 | * use bus address for ih ring by psp bl */ | 664 | * use bus address for ih ring by psp bl */ |
| 663 | use_bus_addr = | 665 | if ((adev->flags & AMD_IS_APU) || |
| 664 | (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) ? false : true; | 666 | (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) |
| 667 | use_bus_addr = false; | ||
| 668 | else | ||
| 669 | use_bus_addr = true; | ||
| 665 | r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 256 * 1024, use_bus_addr); | 670 | r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 256 * 1024, use_bus_addr); |
| 666 | if (r) | 671 | if (r) |
| 667 | return r; | 672 | return r; |
| @@ -28,10 +28,12 @@ · 27 unmodified lines | |||
| 28 | #include "nbio/nbio_2_3_offset.h" | 28 | #include "nbio/nbio_2_3_offset.h" |
| 29 | #include "nbio/nbio_2_3_sh_mask.h" | 29 | #include "nbio/nbio_2_3_sh_mask.h" |
| 30 | #include <uapi/linux/kfd_ioctl.h> | 30 | #include <uapi/linux/kfd_ioctl.h> |
| 31 | #include <linux/pci.h> | ||
| 31 | 32 | ||
| 32 | #define smnPCIE_CONFIG_CNTL 0x11180044 | 33 | #define smnPCIE_CONFIG_CNTL 0x11180044 |
| 33 | #define smnCPM_CONTROL 0x11180460 | 34 | #define smnCPM_CONTROL 0x11180460 |
| 34 | #define smnPCIE_CNTL2 0x11180070 | 35 | #define smnPCIE_CNTL2 0x11180070 |
| 36 | #define smnPCIE_LC_CNTL 0x11140280 | ||
| 35 | 37 | ||
| 36 | #define mmBIF_SDMA2_DOORBELL_RANGE 0x01d6 | 38 | #define mmBIF_SDMA2_DOORBELL_RANGE 0x01d6 |
| 37 | #define mmBIF_SDMA2_DOORBELL_RANGE_BASE_IDX 2 | 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 | WREG32_PCIE(smnPCIE_CONFIG_CNTL, data); | 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 | const struct amdgpu_nbio_funcs nbio_v2_3_funcs = { | 353 | const struct amdgpu_nbio_funcs nbio_v2_3_funcs = { |
| 316 | .get_hdp_flush_req_offset = nbio_v2_3_get_hdp_flush_req_offset, | 354 | .get_hdp_flush_req_offset = nbio_v2_3_get_hdp_flush_req_offset, |
| 317 | .get_hdp_flush_done_offset = nbio_v2_3_get_hdp_flush_done_offset, | 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 | .ih_control = nbio_v2_3_ih_control, | 370 | .ih_control = nbio_v2_3_ih_control, |
| 333 | .init_registers = nbio_v2_3_init_registers, | 371 | .init_registers = nbio_v2_3_init_registers, |
| 334 | .remap_hdp_registers = nbio_v2_3_remap_hdp_registers, | 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 | static u32 nbio_v6_1_get_rev_id(struct amdgpu_device *adev) | 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 | tmp &= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK; | 37 | tmp &= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK; |
| 38 | tmp >>= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT; | 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 | static void nbio_v6_1_ih_doorbell_range(struct amdgpu_device *adev, | 114 | static void nbio_v6_1_ih_doorbell_range(struct amdgpu_device *adev, |
| 115 | bool use_doorbell, int doorbell_index) | 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 | if (use_doorbell) { | 119 | if (use_doorbell) { |
| 120 | ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, OFFSET, doorbell_index); | 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 | static u32 nbio_v7_0_get_rev_id(struct amdgpu_device *adev) | 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 | tmp &= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK; | 48 | tmp &= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK; |
| 49 | tmp >>= RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT; | 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 | static void nbio_v7_0_ih_doorbell_range(struct amdgpu_device *adev, | 126 | static void nbio_v7_0_ih_doorbell_range(struct amdgpu_device *adev, |
| 127 | bool use_doorbell, int doorbell_index) | 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 | if (use_doorbell) { | 131 | if (use_doorbell) { |
| 132 | ih_doorbell_range = REG_SET_FIELD(ih_doorbell_range, BIF_IH_DOORBELL_RANGE, OFFSET, doorbell_index); | 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 | #include "gfxhub_v2_0.h" | 49 | #include "gfxhub_v2_0.h" |
| 50 | #include "mmhub_v2_0.h" | 50 | #include "mmhub_v2_0.h" |
| 51 | #include "nbio_v2_3.h" | 51 | #include "nbio_v2_3.h" |
| 52 | #include "nbio_v7_2.h" | ||
| 52 | #include "nv.h" | 53 | #include "nv.h" |
| 53 | #include "navi10_ih.h" | 54 | #include "navi10_ih.h" |
| 54 | #include "gfx_v10_0.h" | 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 | return amdgpu_device_indirect_rreg64(adev, address, data, reg); | 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 | static void nv_pcie_wreg64(struct amdgpu_device *adev, u32 reg, u64 v) | 114 | static void nv_pcie_wreg64(struct amdgpu_device *adev, u32 reg, u64 v) |
| 99 | { | 115 | { |
| 100 | unsigned long address, data; | 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 | amdgpu_device_indirect_wreg64(adev, address, data, reg, v); | 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 | static u32 nv_didt_rreg(struct amdgpu_device *adev, u32 reg) | 139 | static u32 nv_didt_rreg(struct amdgpu_device *adev, u32 reg) |
| 109 | { | 140 | { |
| 110 | unsigned long flags, address, data; | 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 | *value = 0; | 285 | *value = 0; |
| 255 | for (i = 0; i < ARRAY_SIZE(nv_allowed_read_registers); i++) { | 286 | for (i = 0; i < ARRAY_SIZE(nv_allowed_read_registers); i++) { |
| 256 | en = &nv_allowed_read_registers[i]; | 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 | (adev->reg_offset[en->hwip][en->inst][en->seg] + en->reg_offset)) | 290 | (adev->reg_offset[en->hwip][en->inst][en->seg] + en->reg_offset)) |
| 259 | continue; | 291 | continue; |
| 260 | 292 | ||
| @@ -443,6 +475,12 @@ legacy_init: · 182 unmodified lines | |||
| 443 | case CHIP_NAVY_FLOUNDER: | 475 | case CHIP_NAVY_FLOUNDER: |
| 444 | sienna_cichlid_reg_base_init(adev); | 476 | sienna_cichlid_reg_base_init(adev); |
| 445 | break; | 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 | default: | 484 | default: |
| 447 | return -EINVAL; | 485 | return -EINVAL; |
| 448 | } | 486 | } |
| @@ -455,10 +493,11 @@ void nv_set_virt_ops(struct amdgpu_device *adev) · 6 unmodified lines | |||
| 455 | adev->virt.ops = &xgpu_nv_virt_ops; | 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 && | 498 | if ((pdev->device == 0x731E && |
| 461 | (pdev->revision == 0xC6 || pdev->revision == 0xC7)) | 499 | (pdev->revision == 0xC6 || pdev->revision == 0xC7)) || |
| 500 | (pdev->device == 0x7340 && pdev->revision == 0xC9)) | ||
| 462 | return true; | 501 | return true; |
| 463 | return false; | 502 | return false; |
| 464 | } | 503 | } |
| @@ -467,8 +506,13 @@ int nv_set_ip_blocks(struct amdgpu_device *adev) · 2 unmodified lines | |||
| 467 | { | 506 | { |
| 468 | int r; | 507 | int r; |
| 469 | 508 | ||
| 470 | adev->nbio.funcs = &nbio_v2_3_funcs; | 509 | if (adev->flags & AMD_IS_APU) { |
| 471 | adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg; | 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 | if (adev->asic_type == CHIP_SIENNA_CICHLID) | 517 | if (adev->asic_type == CHIP_SIENNA_CICHLID) |
| 474 | adev->gmc.xgmi.supported = true; | 518 | adev->gmc.xgmi.supported = true; |
| @@ -492,7 +536,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev) · 17 unmodified lines | |||
| 492 | amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); | 536 | amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); |
| 493 | #if defined(CONFIG_DRM_AMD_DC) | 537 | #if defined(CONFIG_DRM_AMD_DC) |
| 494 | else if (amdgpu_device_has_dc_support(adev) && | 538 | else if (amdgpu_device_has_dc_support(adev) && |
| 495 | !nv_is_blockchain_sku(adev->pdev)) | 539 | !nv_is_headless_sku(adev->pdev)) |
| 496 | amdgpu_device_ip_block_add(adev, &dm_ip_block); | 540 | amdgpu_device_ip_block_add(adev, &dm_ip_block); |
| 497 | #endif | 541 | #endif |
| 498 | amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); | 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 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT && | 544 | if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT && |
| 501 | !amdgpu_sriov_vf(adev)) | 545 | !amdgpu_sriov_vf(adev)) |
| 502 | amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); | 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 | amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block); | 548 | amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block); |
| 505 | amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block); | 549 | amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block); |
| 506 | if (adev->enable_mes) | 550 | if (adev->enable_mes) |
| @@ -575,6 +619,44 @@ int nv_set_ip_blocks(struct amdgpu_device *adev) · 68 unmodified lines | |||
| 575 | is_support_sw_smu(adev)) | 619 | is_support_sw_smu(adev)) |
| 576 | amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); | 620 | amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); |
| 577 | break; | 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 | default: | 660 | default: |
| 579 | return -EINVAL; | 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 | static const struct amdgpu_asic_funcs nv_asic_funcs = | 779 | static const struct amdgpu_asic_funcs nv_asic_funcs = |
| 675 | { | 780 | { |
| 676 | .read_disabled_bios = &nv_read_disabled_bios, | 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 | .get_pcie_replay_count = &nv_get_pcie_replay_count, | 796 | .get_pcie_replay_count = &nv_get_pcie_replay_count, |
| 692 | .supports_baco = &nv_asic_supports_baco, | 797 | .supports_baco = &nv_asic_supports_baco, |
| 693 | .pre_asic_init = &nv_pre_asic_init, | 798 | .pre_asic_init = &nv_pre_asic_init, |
| 799 | .update_umd_stable_pstate = &nv_update_umd_stable_pstate, | ||
| 694 | }; | 800 | }; |
| 695 | 801 | ||
| 696 | static int nv_common_early_init(void *handle) | 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 | adev->pcie_wreg = &nv_pcie_wreg; | 812 | adev->pcie_wreg = &nv_pcie_wreg; |
| 707 | adev->pcie_rreg64 = &nv_pcie_rreg64; | 813 | adev->pcie_rreg64 = &nv_pcie_rreg64; |
| 708 | adev->pcie_wreg64 = &nv_pcie_wreg64; | 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 | /* TODO: will add them during VCN v2 implementation */ | 818 | /* TODO: will add them during VCN v2 implementation */ |
| 711 | adev->uvd_ctx_rreg = NULL; | 819 | adev->uvd_ctx_rreg = NULL; |
| @@ -833,6 +941,46 @@ static int nv_common_early_init(void *handle) · 121 unmodified lines | |||
| 833 | adev->external_rev_id = adev->rev_id + 0x32; | 941 | adev->external_rev_id = adev->rev_id + 0x32; |
| 834 | break; | 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 | default: | 984 | default: |
| 837 | /* FIXME: not supported yet */ | 985 | /* FIXME: not supported yet */ |
| 838 | return -EINVAL; | 986 | return -EINVAL; |
| @@ -1060,6 +1208,7 @@ static int nv_common_set_clockgating_state(void *handle, · 221 unmodified lines | |||
| 1060 | case CHIP_NAVI12: | 1208 | case CHIP_NAVI12: |
| 1061 | case CHIP_SIENNA_CICHLID: | 1209 | case CHIP_SIENNA_CICHLID: |
| 1062 | case CHIP_NAVY_FLOUNDER: | 1210 | case CHIP_NAVY_FLOUNDER: |
| 1211 | case CHIP_DIMGREY_CAVEFISH: | ||
| 1063 | adev->nbio.funcs->update_medium_grain_clock_gating(adev, | 1212 | adev->nbio.funcs->update_medium_grain_clock_gating(adev, |
| 1064 | state == AMD_CG_STATE_GATE); | 1213 | state == AMD_CG_STATE_GATE); |
| 1065 | adev->nbio.funcs->update_medium_grain_light_sleep(adev, | 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 | int navi14_reg_base_init(struct amdgpu_device *adev); | 34 | int navi14_reg_base_init(struct amdgpu_device *adev); |
| 35 | int navi12_reg_base_init(struct amdgpu_device *adev); | 35 | int navi12_reg_base_init(struct amdgpu_device *adev); |
| 36 | int sienna_cichlid_reg_base_init(struct amdgpu_device *adev); | 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 | #endif | 39 | #endif |
| @@ -86,21 +86,22 @@ struct psp_gfx_ctrl · 85 unmodified lines | |||
| 86 | /* TEE Gfx Command IDs for the ring buffer interface. */ | 86 | /* TEE Gfx Command IDs for the ring buffer interface. */ |
| 87 | enum psp_gfx_cmd_id | 87 | enum psp_gfx_cmd_id |
| 88 | { | 88 | { |
| 89 | GFX_CMD_ID_LOAD_TA = 0x00000001, /* load TA */ | 89 | GFX_CMD_ID_LOAD_TA = 0x00000001, /* load TA */ |
| 90 | GFX_CMD_ID_UNLOAD_TA = 0x00000002, /* unload TA */ | 90 | GFX_CMD_ID_UNLOAD_TA = 0x00000002, /* unload TA */ |
| 91 | GFX_CMD_ID_INVOKE_CMD = 0x00000003, /* send command to TA */ | 91 | GFX_CMD_ID_INVOKE_CMD = 0x00000003, /* send command to TA */ |
| 92 | GFX_CMD_ID_LOAD_ASD = 0x00000004, /* load ASD Driver */ | 92 | GFX_CMD_ID_LOAD_ASD = 0x00000004, /* load ASD Driver */ |
| 93 | GFX_CMD_ID_SETUP_TMR = 0x00000005, /* setup TMR region */ | 93 | GFX_CMD_ID_SETUP_TMR = 0x00000005, /* setup TMR region */ |
| 94 | GFX_CMD_ID_LOAD_IP_FW = 0x00000006, /* load HW IP FW */ | 94 | GFX_CMD_ID_LOAD_IP_FW = 0x00000006, /* load HW IP FW */ |
| 95 | GFX_CMD_ID_DESTROY_TMR = 0x00000007, /* destroy TMR region */ | 95 | GFX_CMD_ID_DESTROY_TMR = 0x00000007, /* destroy TMR region */ |
| 96 | GFX_CMD_ID_SAVE_RESTORE = 0x00000008, /* save/restore HW IP FW */ | 96 | GFX_CMD_ID_SAVE_RESTORE = 0x00000008, /* save/restore HW IP FW */ |
| 97 | GFX_CMD_ID_SETUP_VMR = 0x00000009, /* setup VMR region */ | 97 | GFX_CMD_ID_SETUP_VMR = 0x00000009, /* setup VMR region */ |
| 98 | GFX_CMD_ID_DESTROY_VMR = 0x0000000A, /* destroy VMR region */ | 98 | GFX_CMD_ID_DESTROY_VMR = 0x0000000A, /* destroy VMR region */ |
| 99 | GFX_CMD_ID_PROG_REG = 0x0000000B, /* program regs */ | 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. */ | 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 | /* IDs upto 0x1F are reserved for older programs (Raven, Vega 10/12/20) */ | 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_LOAD_TOC = 0x00000020, /* Load TOC and obtain TMR size */ |
| 103 | GFX_CMD_ID_AUTOLOAD_RLC = 0x00000021, /* Indicates all graphics fw loaded, start RLC autoload */ | 104 | GFX_CMD_ID_AUTOLOAD_RLC = 0x00000021, /* Indicates all graphics fw loaded, start RLC autoload */ |
| 104 | }; | 105 | }; |
| 105 | 106 | ||
| 106 | /* Command to load Trusted Application binary into PSP OS. */ | 107 | /* Command to load Trusted Application binary into PSP OS. */ |
| @@ -285,6 +286,25 @@ union psp_gfx_commands · 178 unmodified lines | |||
| 285 | struct psp_gfx_cmd_load_toc cmd_load_toc; | 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 | /* Structure of GFX Response buffer. | 308 | /* Structure of GFX Response buffer. |
| 289 | * For GPCOM I/F it is part of GFX_CMD_RESP buffer, for RBI | 309 | * For GPCOM I/F it is part of GFX_CMD_RESP buffer, for RBI |
| 290 | * it is separate buffer. | 310 | * it is separate buffer. |
| @@ -297,9 +317,11 @@ struct psp_gfx_resp · 6 unmodified lines | |||
| 297 | uint32_t fw_addr_hi; /* +12 bits [63:32] of FW address within TMR (in response to cmd_load_ip_fw command) */ | 317 | uint32_t fw_addr_hi; /* +12 bits [63:32] of FW address within TMR (in response to cmd_load_ip_fw command) */ |
| 298 | 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 */ | 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 | /* Structure of Command buffer pointed by psp_gfx_rb_frame.cmd_buf_addr_hi | 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 | MODULE_FIRMWARE("amdgpu/sienna_cichlid_ta.bin"); | 59 | MODULE_FIRMWARE("amdgpu/sienna_cichlid_ta.bin"); |
| 60 | MODULE_FIRMWARE("amdgpu/navy_flounder_sos.bin"); | 60 | MODULE_FIRMWARE("amdgpu/navy_flounder_sos.bin"); |
| 61 | MODULE_FIRMWARE("amdgpu/navy_flounder_ta.bin"); | 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 | /* address block */ | 67 | /* address block */ |
| 64 | #define smnMP1_FIRMWARE_FLAGS 0x3010024 | 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 | struct amdgpu_device *adev = psp->adev; | 82 | struct amdgpu_device *adev = psp->adev; |
| 79 | const char *chip_name; | 83 | const char *chip_name; |
| 80 | char fw_name[30]; | 84 | char fw_name[PSP_FW_NAME_LEN]; |
| 81 | int err = 0; | 85 | int err = 0; |
| 82 | const struct ta_firmware_header_v1_0 *ta_hdr; | 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 | case CHIP_NAVY_FLOUNDER: | 109 | case CHIP_NAVY_FLOUNDER: |
| 106 | chip_name = "navy_flounder"; | 110 | chip_name = "navy_flounder"; |
| 107 | break; | 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 | default: | 118 | default: |
| 109 | BUG(); | 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 | switch (adev->asic_type) { | 123 | switch (adev->asic_type) { |
| 124 | case CHIP_VEGA20: | 124 | case CHIP_VEGA20: |
| 125 | case CHIP_ARCTURUS: | 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 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name); | 132 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name); |
| 127 | err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev); | 133 | err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev); |
| 128 | if (err) { | 134 | if (err) { |
| @@ -150,6 +156,12 @@ static int psp_v11_0_init_microcode(struct psp_context *psp) · 21 unmodified lines | |||
| 150 | case CHIP_NAVI10: | 156 | case CHIP_NAVI10: |
| 151 | case CHIP_NAVI14: | 157 | case CHIP_NAVI14: |
| 152 | case CHIP_NAVI12: | 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 | if (amdgpu_sriov_vf(adev)) | 165 | if (amdgpu_sriov_vf(adev)) |
| 154 | break; | 166 | break; |
| 155 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name); | 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 | break; | 192 | break; |
| 181 | case CHIP_SIENNA_CICHLID: | 193 | case CHIP_SIENNA_CICHLID: |
| 182 | case CHIP_NAVY_FLOUNDER: | 194 | case CHIP_NAVY_FLOUNDER: |
| 195 | err = psp_init_sos_microcode(psp, chip_name); | ||
| 196 | if (err) | ||
| 197 | return err; | ||
| 183 | err = psp_init_ta_microcode(&adev->psp, chip_name); | 198 | err = psp_init_ta_microcode(&adev->psp, chip_name); |
| 184 | if (err) | 199 | if (err) |
| 185 | return err; | 200 | return err; |
| 186 | break; | 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 | default: | 215 | default: |
| 188 | BUG(); | 216 | BUG(); |
| 189 | } | 217 | } |
| @@ -407,8 +435,8 @@ static int psp_v11_0_ring_init(struct psp_context *psp, · 217 unmodified lines | |||
| 407 | struct amdgpu_device *adev = psp->adev; | 435 | struct amdgpu_device *adev = psp->adev; |
| 408 | 436 | ||
| 409 | if ((!amdgpu_sriov_vf(adev)) && | 437 | if ((!amdgpu_sriov_vf(adev)) && |
| 410 | (adev->asic_type != CHIP_SIENNA_CICHLID) && | 438 | !(adev->asic_type >= CHIP_SIENNA_CICHLID && |
| 411 | (adev->asic_type != CHIP_NAVY_FLOUNDER)) | 439 | adev->asic_type <= CHIP_DIMGREY_CAVEFISH)) |
| 412 | psp_v11_0_reroute_ih(psp); | 440 | psp_v11_0_reroute_ih(psp); |
| 413 | 441 | ||
| 414 | ring = &psp->km_ring; | 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 | static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops) | 643 | static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops) |
| 616 | { | 644 | { |
| 617 | struct psp_memory_training_context *ctx = &psp->mem_train_ctx; | 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 | struct amdgpu_device *adev = psp->adev; | 647 | struct amdgpu_device *adev = psp->adev; |
| 620 | uint32_t p2c_header[4]; | 648 | uint32_t p2c_header[4]; |
| 621 | uint32_t sz; | 649 | uint32_t sz; |
| @@ -39,6 +39,7 @@ · 38 unmodified lines | |||
| 39 | 39 | ||
| 40 | MODULE_FIRMWARE("amdgpu/renoir_asd.bin"); | 40 | MODULE_FIRMWARE("amdgpu/renoir_asd.bin"); |
| 41 | MODULE_FIRMWARE("amdgpu/renoir_ta.bin"); | 41 | MODULE_FIRMWARE("amdgpu/renoir_ta.bin"); |
| 42 | MODULE_FIRMWARE("amdgpu/green_sardine_asd.bin"); | ||
| 42 | 43 | ||
| 43 | /* address block */ | 44 | /* address block */ |
| 44 | #define smnMP1_FIRMWARE_FLAGS 0x3010024 | 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 | switch (adev->asic_type) { | 56 | switch (adev->asic_type) { |
| 56 | case CHIP_RENOIR: | 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 | break; | 62 | break; |
| 59 | default: | 63 | default: |
| 60 | BUG(); | 64 | BUG(); |
| @@ -69,6 +69,7 @@ MODULE_FIRMWARE("amdgpu/picasso_sdma.bin"); · 68 unmodified lines | |||
| 69 | MODULE_FIRMWARE("amdgpu/raven2_sdma.bin"); | 69 | MODULE_FIRMWARE("amdgpu/raven2_sdma.bin"); |
| 70 | MODULE_FIRMWARE("amdgpu/arcturus_sdma.bin"); | 70 | MODULE_FIRMWARE("amdgpu/arcturus_sdma.bin"); |
| 71 | MODULE_FIRMWARE("amdgpu/renoir_sdma.bin"); | 71 | MODULE_FIRMWARE("amdgpu/renoir_sdma.bin"); |
| 72 | MODULE_FIRMWARE("amdgpu/green_sardine_sdma.bin"); | ||
| 72 | 73 | ||
| 73 | #define SDMA0_POWER_CNTL__ON_OFF_CONDITION_HOLD_TIME_MASK 0x000000F8L | 74 | #define SDMA0_POWER_CNTL__ON_OFF_CONDITION_HOLD_TIME_MASK 0x000000F8L |
| 74 | #define SDMA0_POWER_CNTL__ON_OFF_STATUS_DURATION_TIME_MASK 0xFC000000L | 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 | break; | 569 | break; |
| 569 | } | 570 | } |
| 570 | 571 | ||
| 571 | memset((void*)adev->sdma.instance, 0, | 572 | memset((void *)adev->sdma.instance, 0, |
| 572 | sizeof(struct amdgpu_sdma_instance) * AMDGPU_MAX_SDMA_INSTANCES); | 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 | chip_name = "arcturus"; | 620 | chip_name = "arcturus"; |
| 620 | break; | 621 | break; |
| 621 | case CHIP_RENOIR: | 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 | break; | 627 | break; |
| 624 | default: | 628 | default: |
| 625 | BUG(); | 629 | BUG(); |
| @@ -639,8 +643,8 @@ static int sdma_v4_0_init_microcode(struct amdgpu_device *adev) · 13 unmodified lines | |||
| 639 | if (adev->asic_type == CHIP_ARCTURUS) { | 643 | if (adev->asic_type == CHIP_ARCTURUS) { |
| 640 | /* Acturus will leverage the same FW memory | 644 | /* Acturus will leverage the same FW memory |
| 641 | for every SDMA instance */ | 645 | for every SDMA instance */ |
| 642 | memcpy((void*)&adev->sdma.instance[i], | 646 | memcpy((void *)&adev->sdma.instance[i], |
| 643 | (void*)&adev->sdma.instance[0], | 647 | (void *)&adev->sdma.instance[0], |
| 644 | sizeof(struct amdgpu_sdma_instance)); | 648 | sizeof(struct amdgpu_sdma_instance)); |
| 645 | } | 649 | } |
| 646 | else { | 650 | else { |
| @@ -46,6 +46,9 @@ · 45 unmodified lines | |||
| 46 | 46 | ||
| 47 | MODULE_FIRMWARE("amdgpu/sienna_cichlid_sdma.bin"); | 47 | MODULE_FIRMWARE("amdgpu/sienna_cichlid_sdma.bin"); |
| 48 | MODULE_FIRMWARE("amdgpu/navy_flounder_sdma.bin"); | 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 | #define SDMA1_REG_OFFSET 0x600 | 53 | #define SDMA1_REG_OFFSET 0x600 |
| 51 | #define SDMA3_REG_OFFSET 0x400 | 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 | switch (adev->asic_type) { | 90 | switch (adev->asic_type) { |
| 88 | case CHIP_SIENNA_CICHLID: | 91 | case CHIP_SIENNA_CICHLID: |
| 89 | case CHIP_NAVY_FLOUNDER: | 92 | case CHIP_NAVY_FLOUNDER: |
| 93 | case CHIP_VANGOGH: | ||
| 94 | case CHIP_DIMGREY_CAVEFISH: | ||
| 90 | break; | 95 | break; |
| 91 | default: | 96 | default: |
| 92 | break; | 97 | break; |
| @@ -124,7 +129,7 @@ static void sdma_v5_2_destroy_inst_ctx(struct amdgpu_device *adev) · 31 unmodified lines | |||
| 124 | break; | 129 | break; |
| 125 | } | 130 | } |
| 126 | 131 | ||
| 127 | memset((void*)adev->sdma.instance, 0, | 132 | memset((void *)adev->sdma.instance, 0, |
| 128 | sizeof(struct amdgpu_sdma_instance) * AMDGPU_MAX_SDMA_INSTANCES); | 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 | case CHIP_NAVY_FLOUNDER: | 165 | case CHIP_NAVY_FLOUNDER: |
| 161 | chip_name = "navy_flounder"; | 166 | chip_name = "navy_flounder"; |
| 162 | break; | 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 | default: | 174 | default: |
| 164 | BUG(); | 175 | BUG(); |
| 165 | } | 176 | } |
| @@ -175,10 +186,10 @@ static int sdma_v5_2_init_microcode(struct amdgpu_device *adev) · 9 unmodified lines | |||
| 175 | goto out; | 186 | goto out; |
| 176 | 187 | ||
| 177 | for (i = 1; i < adev->sdma.num_instances; i++) { | 188 | for (i = 1; i < adev->sdma.num_instances; i++) { |
| 178 | if (adev->asic_type == CHIP_SIENNA_CICHLID || | 189 | if (adev->asic_type >= CHIP_SIENNA_CICHLID && |
| 179 | adev->asic_type == CHIP_NAVY_FLOUNDER) { | 190 | adev->asic_type <= CHIP_DIMGREY_CAVEFISH) { |
| 180 | memcpy((void*)&adev->sdma.instance[i], | 191 | memcpy((void *)&adev->sdma.instance[i], |
| 181 | (void*)&adev->sdma.instance[0], | 192 | (void *)&adev->sdma.instance[0], |
| 182 | sizeof(struct amdgpu_sdma_instance)); | 193 | sizeof(struct amdgpu_sdma_instance)); |
| 183 | } else { | 194 | } else { |
| 184 | snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_sdma%d.bin", chip_name, i); | 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 | temp &= 0xFF0FFF; | 707 | temp &= 0xFF0FFF; |
| 697 | temp |= ((CACHE_READ_POLICY_L2__DEFAULT << 12) | | 708 | temp |= ((CACHE_READ_POLICY_L2__DEFAULT << 12) | |
| 698 | (CACHE_WRITE_POLICY_L2__DEFAULT << 14) | | 709 | (CACHE_WRITE_POLICY_L2__DEFAULT << 14) | |
| 699 | 0x01000000); | 710 | SDMA0_UTCL1_PAGE__LLC_NOALLOC_MASK); |
| 700 | WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_UTCL1_PAGE), temp); | 711 | WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_UTCL1_PAGE), temp); |
| 701 | 712 | ||
| 702 | if (!amdgpu_sriov_vf(adev)) { | 713 | if (!amdgpu_sriov_vf(adev)) { |
| @@ -1169,8 +1180,12 @@ static int sdma_v5_2_early_init(void *handle) · 466 unmodified lines | |||
| 1169 | adev->sdma.num_instances = 4; | 1180 | adev->sdma.num_instances = 4; |
| 1170 | break; | 1181 | break; |
| 1171 | case CHIP_NAVY_FLOUNDER: | 1182 | case CHIP_NAVY_FLOUNDER: |
| 1183 | case CHIP_DIMGREY_CAVEFISH: | ||
| 1172 | adev->sdma.num_instances = 2; | 1184 | adev->sdma.num_instances = 2; |
| 1173 | break; | 1185 | break; |
| 1186 | case CHIP_VANGOGH: | ||
| 1187 | adev->sdma.num_instances = 1; | ||
| 1188 | break; | ||
| 1174 | default: | 1189 | default: |
| 1175 | break; | 1190 | break; |
| 1176 | } | 1191 | } |
| @@ -1567,6 +1582,8 @@ static int sdma_v5_2_set_clockgating_state(void *handle, · 390 unmodified lines | |||
| 1567 | switch (adev->asic_type) { | 1582 | switch (adev->asic_type) { |
| 1568 | case CHIP_SIENNA_CICHLID: | 1583 | case CHIP_SIENNA_CICHLID: |
| 1569 | case CHIP_NAVY_FLOUNDER: | 1584 | case CHIP_NAVY_FLOUNDER: |
| 1585 | case CHIP_VANGOGH: | ||
| 1586 | case CHIP_DIMGREY_CAVEFISH: | ||
| 1570 | sdma_v5_2_update_medium_grain_clock_gating(adev, | 1587 | sdma_v5_2_update_medium_grain_clock_gating(adev, |
| 1571 | state == AMD_CG_STATE_GATE ? true : false); | 1588 | state == AMD_CG_STATE_GATE ? true : false); |
| 1572 | sdma_v5_2_update_medium_grain_light_sleep(adev, | 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 | static u32 si_get_xclk(struct amdgpu_device *adev) | 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 | u32 tmp; | 1354 | u32 tmp; |
| 1355 | 1355 | ||
| 1356 | tmp = RREG32(CG_CLKPIN_CNTL_2); | 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 | WREG32(IH_RB_CNTL, ih_rb_cntl); | 43 | WREG32(IH_RB_CNTL, ih_rb_cntl); |
| 44 | adev->irq.ih.enabled = true; | 44 | adev->irq.ih.enabled = true; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | static void si_ih_disable_interrupts(struct amdgpu_device *adev) | 47 | static void si_ih_disable_interrupts(struct amdgpu_device *adev) |
| 48 | { | 48 | { |
| 49 | u32 ih_rb_cntl = RREG32(IH_RB_CNTL); | 49 | u32 ih_rb_cntl = RREG32(IH_RB_CNTL); |
| @@ -62,6 +62,7 @@ · 61 unmodified lines | |||
| 62 | #include "nbio_v7_0.h" | 62 | #include "nbio_v7_0.h" |
| 63 | #include "nbio_v7_4.h" | 63 | #include "nbio_v7_4.h" |
| 64 | #include "vega10_ih.h" | 64 | #include "vega10_ih.h" |
| 65 | #include "navi10_ih.h" | ||
| 65 | #include "sdma_v4_0.h" | 66 | #include "sdma_v4_0.h" |
| 66 | #include "uvd_v7_0.h" | 67 | #include "uvd_v7_0.h" |
| 67 | #include "vce_v4_0.h" | 68 | #include "vce_v4_0.h" |
| @@ -734,9 +735,15 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev) · 666 unmodified lines | |||
| 734 | else | 735 | else |
| 735 | amdgpu_device_ip_block_add(adev, &psp_v3_1_ip_block); | 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 | } else { | 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 | if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) { | 747 | if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) { |
| 741 | if (adev->asic_type == CHIP_VEGA20) | 748 | if (adev->asic_type == CHIP_VEGA20) |
| 742 | amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); | 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 | if (amdgpu_sriov_vf(adev)) { | 794 | if (amdgpu_sriov_vf(adev)) { |
| 788 | if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) | 795 | if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) |
| 789 | amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); | 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 | } else { | 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 | if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) | 800 | if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) |
| 794 | amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); | 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 | amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); | 829 | amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); |
| 823 | #if defined(CONFIG_DRM_AMD_DC) | 830 | #if defined(CONFIG_DRM_AMD_DC) |
| 824 | else if (amdgpu_device_has_dc_support(adev)) | 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 | #endif | 833 | #endif |
| 827 | amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block); | 834 | amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block); |
| 828 | amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block); | 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 | adev->pg_flags = AMD_PG_SUPPORT_SDMA | | 1203 | adev->pg_flags = AMD_PG_SUPPORT_SDMA | |
| 1197 | AMD_PG_SUPPORT_MMHUB | | 1204 | AMD_PG_SUPPORT_MMHUB | |
| 1198 | AMD_PG_SUPPORT_VCN | | 1205 | AMD_PG_SUPPORT_VCN; |
| 1199 | AMD_PG_SUPPORT_VCN_DPG; | ||
| 1200 | } else { | 1206 | } else { |
| 1201 | adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | | 1207 | adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | |
| 1202 | AMD_CG_SUPPORT_GFX_MGLS | | 1208 | AMD_CG_SUPPORT_GFX_MGLS | |
| @@ -1243,7 +1249,15 @@ static int soc15_common_early_init(void *handle) · 40 unmodified lines | |||
| 1243 | break; | 1249 | break; |
| 1244 | case CHIP_RENOIR: | 1250 | case CHIP_RENOIR: |
| 1245 | adev->asic_funcs = &soc15_asic_funcs; | 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 | adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | | 1261 | adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | |
| 1248 | AMD_CG_SUPPORT_GFX_MGLS | | 1262 | AMD_CG_SUPPORT_GFX_MGLS | |
| 1249 | AMD_CG_SUPPORT_GFX_3D_CGCG | | 1263 | AMD_CG_SUPPORT_GFX_3D_CGCG | |
| @@ -1268,7 +1282,6 @@ static int soc15_common_early_init(void *handle) · 18 unmodified lines | |||
| 1268 | AMD_PG_SUPPORT_VCN | | 1282 | AMD_PG_SUPPORT_VCN | |
| 1269 | AMD_PG_SUPPORT_JPEG | | 1283 | AMD_PG_SUPPORT_JPEG | |
| 1270 | AMD_PG_SUPPORT_VCN_DPG; | 1284 | AMD_PG_SUPPORT_VCN_DPG; |
| 1271 | adev->external_rev_id = adev->rev_id + 0x91; | ||
| 1272 | break; | 1285 | break; |
| 1273 | default: | 1286 | default: |
| 1274 | /* FIXME: not supported yet */ | 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 | static void umc_v6_1_query_ras_error_count(struct amdgpu_device *adev, | 253 | static void umc_v6_1_query_ras_error_count(struct amdgpu_device *adev, |
| 254 | void *ras_error_status) | 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 | uint32_t umc_inst = 0; | 258 | uint32_t umc_inst = 0; |
| 259 | uint32_t ch_inst = 0; | 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 | static void umc_v6_1_query_ras_error_address(struct amdgpu_device *adev, | 368 | static void umc_v6_1_query_ras_error_address(struct amdgpu_device *adev, |
| 369 | void *ras_error_status) | 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 | uint32_t umc_inst = 0; | 373 | uint32_t umc_inst = 0; |
| 374 | uint32_t ch_inst = 0; | 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 | static void umc_v8_7_query_ras_error_count(struct amdgpu_device *adev, | 170 | static void umc_v8_7_query_ras_error_count(struct amdgpu_device *adev, |
| 171 | void *ras_error_status) | 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 | uint32_t umc_inst = 0; | 175 | uint32_t umc_inst = 0; |
| 176 | uint32_t ch_inst = 0; | 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 | static void umc_v8_7_query_ras_error_address(struct amdgpu_device *adev, | 260 | static void umc_v8_7_query_ras_error_address(struct amdgpu_device *adev, |
| 261 | void *ras_error_status) | 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 | uint32_t umc_inst = 0; | 265 | uint32_t umc_inst = 0; |
| 266 | uint32_t ch_inst = 0; | 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 | #define mmUVD_SCRATCH9_INTERNAL_OFFSET 0xc01d | 45 | #define mmUVD_SCRATCH9_INTERNAL_OFFSET 0xc01d |
| 46 | 46 | ||
| 47 | #define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET 0x1e1 | 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 | #define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x5a7 | 49 | #define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x5a7 |
| 50 | #define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET 0x1e2 | 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 | WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, tmp); | 800 | WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, tmp); |
| 801 | 801 | ||
| 802 | if (indirect) | 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 | /* enable clock gating */ | 805 | /* enable clock gating */ |
| 806 | vcn_v2_0_clock_gating_dpg_mode(adev, 0, indirect); | 806 | vcn_v2_0_clock_gating_dpg_mode(adev, 0, indirect); |
| @@ -45,7 +45,7 @@ · 44 unmodified lines | |||
| 45 | 45 | ||
| 46 | #define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET 0x431 | 46 | #define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET 0x431 |
| 47 | #define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x3b4 | 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 | #define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET 0x25c | 49 | #define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET 0x25c |
| 50 | 50 | ||
| 51 | #define VCN25_MAX_HW_INSTANCES_ARCTURUS 2 | 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 | WREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS, tmp); | 777 | WREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS, tmp); |
| 778 | 778 | ||
| 779 | if (indirect) | 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 | /* enable clock gating */ | 782 | /* enable clock gating */ |
| 783 | vcn_v2_5_clock_gating_dpg_mode(adev, 0, inst_idx, indirect); | 783 | vcn_v2_5_clock_gating_dpg_mode(adev, 0, inst_idx, indirect); |
| @@ -44,10 +44,10 @@ · 43 unmodified lines | |||
| 44 | 44 | ||
| 45 | #define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET 0x431 | 45 | #define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET 0x431 |
| 46 | #define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET 0x3b4 | 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 | #define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET 0x25c | 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 | static int amdgpu_ih_clientid_vcns[] = { | 52 | static int amdgpu_ih_clientid_vcns[] = { |
| 53 | SOC15_IH_CLIENTID_VCN, | 53 | SOC15_IH_CLIENTID_VCN, |
| @@ -55,8 +55,8 @@ static int amdgpu_ih_clientid_vcns[] = { · 1 unmodified line | |||
| 55 | }; | 55 | }; |
| 56 | 56 | ||
| 57 | static int amdgpu_ucode_id_vcns[] = { | 57 | static int amdgpu_ucode_id_vcns[] = { |
| 58 | AMDGPU_UCODE_ID_VCN, | 58 | AMDGPU_UCODE_ID_VCN, |
| 59 | AMDGPU_UCODE_ID_VCN1 | 59 | AMDGPU_UCODE_ID_VCN1 |
| 60 | }; | 60 | }; |
| 61 | 61 | ||
| 62 | static int vcn_v3_0_start_sriov(struct amdgpu_device *adev); | 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 | WREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS, tmp); | 915 | WREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS, tmp); |
| 916 | 916 | ||
| 917 | if (indirect) | 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 | /* enable clock gating */ | 920 | /* enable clock gating */ |
| 921 | vcn_v3_0_clock_gating_dpg_mode(adev, 0, inst_idx, indirect); | 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 | /* Update init table header in memory */ | 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 | table_loc = (uint32_t *)table->cpu_addr; | 1375 | table_loc = (uint32_t *)table->cpu_addr; |
| 1376 | memcpy((void *)table_loc, &header, size); | 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 | vmid = (ihre->ring_id & 0x0000ff00) >> 8; | 66 | vmid = (ihre->ring_id & 0x0000ff00) >> 8; |
| 67 | if (vmid < dev->vm_info.first_vmid_kfd || | 67 | if (vmid < dev->vm_info.first_vmid_kfd || |
| 68 | vmid > dev->vm_info.last_vmid_kfd) | 68 | vmid > dev->vm_info.last_vmid_kfd) |
| 69 | return 0; | 69 | return false; |
| 70 | 70 | ||
| 71 | /* If there is no valid PASID, it's likely a firmware bug */ | 71 | /* If there is no valid PASID, it's likely a firmware bug */ |
| 72 | pasid = (ihre->ring_id & 0xffff0000) >> 16; | 72 | pasid = (ihre->ring_id & 0xffff0000) >> 16; |
| 73 | if (WARN_ONCE(pasid == 0, "FW bug: No PASID in KFD interrupt")) | 73 | if (WARN_ONCE(pasid == 0, "FW bug: No PASID in KFD interrupt")) |
| 74 | return 0; | 74 | return false; |
| 75 | 75 | ||
| 76 | /* Interrupt types we care about: various signals and faults. | 76 | /* Interrupt types we care about: various signals and faults. |
| 77 | * They will be forwarded to a work queue (see below). | 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 | #define renoir_cache_info carrizo_cache_info | 141 | #define renoir_cache_info carrizo_cache_info |
| 142 | /* TODO - check & update Navi10 cache details */ | 142 | /* TODO - check & update Navi10 cache details */ |
| 143 | #define navi10_cache_info carrizo_cache_info | 143 | #define navi10_cache_info carrizo_cache_info |
| 144 | #define vangogh_cache_info carrizo_cache_info | ||
| 144 | 145 | ||
| 145 | static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev, | 146 | static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev, |
| 146 | struct crat_subtype_computeunit *cu) | 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 | case CHIP_NAVI14: | 681 | case CHIP_NAVI14: |
| 681 | case CHIP_SIENNA_CICHLID: | 682 | case CHIP_SIENNA_CICHLID: |
| 682 | case CHIP_NAVY_FLOUNDER: | 683 | case CHIP_NAVY_FLOUNDER: |
| 684 | case CHIP_DIMGREY_CAVEFISH: | ||
| 683 | pcache_info = navi10_cache_info; | 685 | pcache_info = navi10_cache_info; |
| 684 | num_of_cache_types = ARRAY_SIZE(navi10_cache_info); | 686 | num_of_cache_types = ARRAY_SIZE(navi10_cache_info); |
| 685 | break; | 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 | default: | 692 | default: |
| 687 | return -EINVAL; | 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 | pcrat_image = kvmalloc(crat_table->length, GFP_KERNEL); | 806 | pcrat_image = kvmalloc(crat_table->length, GFP_KERNEL); |
| 801 | memcpy(pcrat_image, crat_table, crat_table->length); | ||
| 802 | if (!pcrat_image) | 807 | if (!pcrat_image) |
| 803 | return -ENOMEM; | 808 | return -ENOMEM; |
| 804 | 809 | ||
| 810 | memcpy(pcrat_image, crat_table, crat_table->length); | ||
| 805 | *crat_image = pcrat_image; | 811 | *crat_image = pcrat_image; |
| 806 | *size = crat_table->length; | 812 | *size = crat_table->length; |
| 807 | 813 | ||
| @@ -76,6 +76,8 @@ static const struct kfd2kgd_calls *kfd2kgd_funcs[] = { · 75 unmodified lines | |||
| 76 | [CHIP_NAVI14] = &gfx_v10_kfd2kgd, | 76 | [CHIP_NAVI14] = &gfx_v10_kfd2kgd, |
| 77 | [CHIP_SIENNA_CICHLID] = &gfx_v10_3_kfd2kgd, | 77 | [CHIP_SIENNA_CICHLID] = &gfx_v10_3_kfd2kgd, |
| 78 | [CHIP_NAVY_FLOUNDER] = &gfx_v10_3_kfd2kgd, | 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 | #ifdef KFD_SUPPORT_IOMMU_V2 | 83 | #ifdef KFD_SUPPORT_IOMMU_V2 |
| @@ -498,6 +500,43 @@ static const struct kfd_device_info navy_flounder_device_info = { · 416 unmodified lines | |||
| 498 | .num_sdma_queues_per_engine = 8, | 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 | /* For each entry, [0] is regular and [1] is virtualisation device. */ | 540 | /* For each entry, [0] is regular and [1] is virtualisation device. */ |
| 502 | static const struct kfd_device_info *kfd_supported_devices[][2] = { | 541 | static const struct kfd_device_info *kfd_supported_devices[][2] = { |
| 503 | #ifdef KFD_SUPPORT_IOMMU_V2 | 542 | #ifdef KFD_SUPPORT_IOMMU_V2 |
| @@ -522,6 +561,8 @@ static const struct kfd_device_info *kfd_supported_devices[][2] = { · 18 unmodified lines | |||
| 522 | [CHIP_NAVI14] = {&navi14_device_info, NULL}, | 561 | [CHIP_NAVI14] = {&navi14_device_info, NULL}, |
| 523 | [CHIP_SIENNA_CICHLID] = {&sienna_cichlid_device_info, &sienna_cichlid_device_info}, | 562 | [CHIP_SIENNA_CICHLID] = {&sienna_cichlid_device_info, &sienna_cichlid_device_info}, |
| 524 | [CHIP_NAVY_FLOUNDER] = {&navy_flounder_device_info, &navy_flounder_device_info}, | 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 | static int kfd_gtt_sa_init(struct kfd_dev *kfd, unsigned int buf_size, | 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 | kfd->hive_id = amdgpu_amdkfd_get_hive_id(kfd->kgd); | 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 | kfd->noretry = amdgpu_amdkfd_get_noretry(kfd->kgd); | 760 | kfd->noretry = amdgpu_amdkfd_get_noretry(kfd->kgd); |
| 722 | 761 | ||
| 723 | if (kfd_interrupt_init(kfd)) { | 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 | case CHIP_NAVI14: | 1925 | case CHIP_NAVI14: |
| 1926 | case CHIP_SIENNA_CICHLID: | 1926 | case CHIP_SIENNA_CICHLID: |
| 1927 | case CHIP_NAVY_FLOUNDER: | 1927 | case CHIP_NAVY_FLOUNDER: |
| 1928 | case CHIP_VANGOGH: | ||
| 1929 | case CHIP_DIMGREY_CAVEFISH: | ||
| 1928 | device_queue_manager_init_v10_navi10(&dqm->asic_ops); | 1930 | device_queue_manager_init_v10_navi10(&dqm->asic_ops); |
| 1929 | break; | 1931 | break; |
| 1930 | default: | 1932 | default: |
| @@ -417,6 +417,8 @@ int kfd_init_apertures(struct kfd_process *process) · 416 unmodified lines | |||
| 417 | case CHIP_NAVI14: | 417 | case CHIP_NAVI14: |
| 418 | case CHIP_SIENNA_CICHLID: | 418 | case CHIP_SIENNA_CICHLID: |
| 419 | case CHIP_NAVY_FLOUNDER: | 419 | case CHIP_NAVY_FLOUNDER: |
| 420 | case CHIP_VANGOGH: | ||
| 421 | case CHIP_DIMGREY_CAVEFISH: | ||
| 420 | kfd_init_apertures_v9(pdd, id); | 422 | kfd_init_apertures_v9(pdd, id); |
| 421 | break; | 423 | break; |
| 422 | default: | 424 | default: |
| @@ -247,6 +247,8 @@ int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm) · 246 unmodified lines | |||
| 247 | case CHIP_NAVI14: | 247 | case CHIP_NAVI14: |
| 248 | case CHIP_SIENNA_CICHLID: | 248 | case CHIP_SIENNA_CICHLID: |
| 249 | case CHIP_NAVY_FLOUNDER: | 249 | case CHIP_NAVY_FLOUNDER: |
| 250 | case CHIP_VANGOGH: | ||
| 251 | case CHIP_DIMGREY_CAVEFISH: | ||
| 250 | pm->pmf = &kfd_v9_pm_funcs; | 252 | pm->pmf = &kfd_v9_pm_funcs; |
| 251 | break; | 253 | break; |
| 252 | default: | 254 | default: |
| @@ -292,9 +292,6 @@ struct kfd_dev { · 291 unmodified lines | |||
| 292 | /* xGMI */ | 292 | /* xGMI */ |
| 293 | uint64_t hive_id; | 293 | uint64_t hive_id; |
| 294 | 294 | ||
| 295 | /* UUID */ | ||
| 296 | uint64_t unique_id; | ||
| 297 | |||
| 298 | bool pci_atomic_requested; | 295 | bool pci_atomic_requested; |
| 299 | 296 | ||
| 300 | /* Use IOMMU v2 flag */ | 297 | /* Use IOMMU v2 flag */ |
| @@ -1340,7 +1340,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu) · 1339 unmodified lines | |||
| 1340 | dev->gpu->dqm->sched_policy != KFD_SCHED_POLICY_NO_HWS) ? | 1340 | dev->gpu->dqm->sched_policy != KFD_SCHED_POLICY_NO_HWS) ? |
| 1341 | amdgpu_amdkfd_get_num_gws(dev->gpu->kgd) : 0; | 1341 | amdgpu_amdkfd_get_num_gws(dev->gpu->kgd) : 0; |
| 1342 | dev->node_props.num_cp_queues = get_cp_queues_num(dev->gpu->dqm); | 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 | kfd_fill_mem_clk_max_info(dev); | 1345 | kfd_fill_mem_clk_max_info(dev); |
| 1346 | kfd_fill_iolink_non_crat_info(dev); | 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 | case CHIP_NAVI14: | 1375 | case CHIP_NAVI14: |
| 1376 | case CHIP_SIENNA_CICHLID: | 1376 | case CHIP_SIENNA_CICHLID: |
| 1377 | case CHIP_NAVY_FLOUNDER: | 1377 | case CHIP_NAVY_FLOUNDER: |
| 1378 | case CHIP_VANGOGH: | ||
| 1379 | case CHIP_DIMGREY_CAVEFISH: | ||
| 1378 | dev->node_props.capability |= ((HSA_CAP_DOORBELL_TYPE_2_0 << | 1380 | dev->node_props.capability |= ((HSA_CAP_DOORBELL_TYPE_2_0 << |
| 1379 | HSA_CAP_DOORBELL_TYPE_TOTALBITS_SHIFT) & | 1381 | HSA_CAP_DOORBELL_TYPE_TOTALBITS_SHIFT) & |
| 1380 | HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK); | 1382 | HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK); |
| @@ -15,15 +15,7 @@ config DRM_AMD_DC · 14 unmodified lines | |||
| 15 | config DRM_AMD_DC_DCN | 15 | config DRM_AMD_DC_DCN |
| 16 | def_bool n | 16 | def_bool n |
| 17 | help | 17 | help |
| 18 | Raven, Navi and Renoir family support for display engine | 18 | Raven, Navi, and newer 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 | ||
| 27 | 19 | ||
| 28 | config DRM_AMD_DC_HDCP | 20 | config DRM_AMD_DC_HDCP |
| 29 | bool "Enable HDCP support in DC" | 21 | bool "Enable HDCP support in DC" |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | |||
| 34 | #include "dc/inc/hw/dmcu.h" | 34 | #include "dc/inc/hw/dmcu.h" |
| 35 | #include "dc/inc/hw/abm.h" | 35 | #include "dc/inc/hw/abm.h" |
| 36 | #include "dc/dc_dmub_srv.h" | 36 | #include "dc/dc_dmub_srv.h" |
| 37 | #include "amdgpu_dm_trace.h" | ||
| 37 | 38 | ||
| 38 | #include "vid.h" | 39 | #include "vid.h" |
| 39 | #include "amdgpu.h" | 40 | #include "amdgpu.h" |
| @@ -94,12 +95,16 @@ · 54 unmodified lines | |||
| 94 | 95 | ||
| 95 | #define FIRMWARE_RENOIR_DMUB "amdgpu/renoir_dmcub.bin" | 96 | #define FIRMWARE_RENOIR_DMUB "amdgpu/renoir_dmcub.bin" |
| 96 | MODULE_FIRMWARE(FIRMWARE_RENOIR_DMUB); | 97 | MODULE_FIRMWARE(FIRMWARE_RENOIR_DMUB); |
| 97 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 98 | #define FIRMWARE_SIENNA_CICHLID_DMUB "amdgpu/sienna_cichlid_dmcub.bin" | 98 | #define FIRMWARE_SIENNA_CICHLID_DMUB "amdgpu/sienna_cichlid_dmcub.bin" |
| 99 | MODULE_FIRMWARE(FIRMWARE_SIENNA_CICHLID_DMUB); | 99 | MODULE_FIRMWARE(FIRMWARE_SIENNA_CICHLID_DMUB); |
| 100 | #define FIRMWARE_NAVY_FLOUNDER_DMUB "amdgpu/navy_flounder_dmcub.bin" | 100 | #define FIRMWARE_NAVY_FLOUNDER_DMUB "amdgpu/navy_flounder_dmcub.bin" |
| 101 | MODULE_FIRMWARE(FIRMWARE_NAVY_FLOUNDER_DMUB); | 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 | #define FIRMWARE_RAVEN_DMCU "amdgpu/raven_dmcu.bin" | 109 | #define FIRMWARE_RAVEN_DMCU "amdgpu/raven_dmcu.bin" |
| 105 | MODULE_FIRMWARE(FIRMWARE_RAVEN_DMCU); | 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 | static bool amdgpu_dm_psr_disable(struct dc_stream_state *stream); | 214 | static bool amdgpu_dm_psr_disable(struct dc_stream_state *stream); |
| 210 | static bool amdgpu_dm_psr_disable_all(struct amdgpu_display_manager *dm); | 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 | * dm_vblank_get_counter | 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 | struct drm_device *dev = connector->dev; | 592 | struct drm_device *dev = connector->dev; |
| 585 | struct amdgpu_device *adev = drm_to_adev(dev); | 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 | struct amdgpu_dm_connector *aconn = to_amdgpu_dm_connector(connector); | 595 | struct amdgpu_dm_connector *aconn = to_amdgpu_dm_connector(connector); |
| 588 | struct drm_display_mode *mode; | 596 | struct drm_display_mode *mode; |
| 589 | unsigned long max_size = 0; | 597 | unsigned long max_size = 0; |
| @@ -880,44 +888,60 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) · 290 unmodified lines | |||
| 880 | return 0; | 888 | return 0; |
| 881 | } | 889 | } |
| 882 | 890 | ||
| 883 | static void amdgpu_check_debugfs_connector_property_change(struct amdgpu_device *adev, | 891 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| 884 | struct drm_atomic_state *state) | 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; | 894 | uint64_t pt_base; |
| 887 | struct drm_crtc *crtc; | 895 | uint32_t logical_addr_low; |
| 888 | struct amdgpu_dm_connector *amdgpu_dm_connector; | 896 | uint32_t logical_addr_high; |
| 889 | struct drm_connector_state *conn_state; | 897 | uint32_t agp_base, agp_bot, agp_top; |
| 890 | struct dm_crtc_state *acrtc_state; | 898 | PHYSICAL_ADDRESS_LOC page_table_start, page_table_end, page_table_base; |
| 891 | struct drm_crtc_state *crtc_state; | ||
| 892 | struct dc_stream_state *stream; | ||
| 893 | struct drm_device *dev = adev_to_drm(adev); | ||
| 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); | 903 | if (adev->apu_flags & AMD_APU_IS_RAVEN2) |
| 898 | conn_state = connector->state; | 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)) | 914 | agp_base = 0; |
| 901 | continue; | 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)) | 919 | page_table_start.high_part = (u32)(adev->gmc.gart_start >> 44) & 0xF; |
| 907 | continue; | 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 | static int amdgpu_dm_init(struct amdgpu_device *adev) | 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 | case CHIP_RAVEN: | 997 | case CHIP_RAVEN: |
| 974 | case CHIP_RENOIR: | 998 | case CHIP_RENOIR: |
| 975 | init_data.flags.gpu_vm_support = true; | 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 | break; | 1002 | break; |
| 977 | default: | 1003 | default: |
| 978 | break; | 1004 | break; |
| @@ -1026,6 +1052,17 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) · 47 unmodified lines | |||
| 1026 | 1052 | ||
| 1027 | dc_hardware_init(adev->dm.dc); | 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 | adev->dm.freesync_module = mod_freesync_create(adev->dm.dc); | 1066 | adev->dm.freesync_module = mod_freesync_create(adev->dm.dc); |
| 1030 | if (!adev->dm.freesync_module) { | 1067 | if (!adev->dm.freesync_module) { |
| 1031 | DRM_ERROR( | 1068 | DRM_ERROR( |
| @@ -1072,6 +1109,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) · 40 unmodified lines | |||
| 1072 | goto error; | 1109 | goto error; |
| 1073 | } | 1110 | } |
| 1074 | 1111 | ||
| 1112 | |||
| 1075 | DRM_DEBUG_DRIVER("KMS initialized.\n"); | 1113 | DRM_DEBUG_DRIVER("KMS initialized.\n"); |
| 1076 | 1114 | ||
| 1077 | return 0; | 1115 | return 0; |
| @@ -1168,10 +1206,10 @@ static int load_dmcu_fw(struct amdgpu_device *adev) · 90 unmodified lines | |||
| 1168 | case CHIP_NAVI10: | 1206 | case CHIP_NAVI10: |
| 1169 | case CHIP_NAVI14: | 1207 | case CHIP_NAVI14: |
| 1170 | case CHIP_RENOIR: | 1208 | case CHIP_RENOIR: |
| 1171 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 1172 | case CHIP_SIENNA_CICHLID: | 1209 | case CHIP_SIENNA_CICHLID: |
| 1173 | case CHIP_NAVY_FLOUNDER: | 1210 | case CHIP_NAVY_FLOUNDER: |
| 1174 | #endif | 1211 | case CHIP_DIMGREY_CAVEFISH: |
| 1212 | case CHIP_VANGOGH: | ||
| 1175 | return 0; | 1213 | return 0; |
| 1176 | case CHIP_NAVI12: | 1214 | case CHIP_NAVI12: |
| 1177 | fw_name_dmcu = FIRMWARE_NAVI12_DMCU; | 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 | case CHIP_RENOIR: | 1305 | case CHIP_RENOIR: |
| 1268 | dmub_asic = DMUB_ASIC_DCN21; | 1306 | dmub_asic = DMUB_ASIC_DCN21; |
| 1269 | fw_name_dmub = FIRMWARE_RENOIR_DMUB; | 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 | break; | 1310 | break; |
| 1271 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 1272 | case CHIP_SIENNA_CICHLID: | 1311 | case CHIP_SIENNA_CICHLID: |
| 1273 | dmub_asic = DMUB_ASIC_DCN30; | 1312 | dmub_asic = DMUB_ASIC_DCN30; |
| 1274 | fw_name_dmub = FIRMWARE_SIENNA_CICHLID_DMUB; | 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 | dmub_asic = DMUB_ASIC_DCN30; | 1316 | dmub_asic = DMUB_ASIC_DCN30; |
| 1278 | fw_name_dmub = FIRMWARE_NAVY_FLOUNDER_DMUB; | 1317 | fw_name_dmub = FIRMWARE_NAVY_FLOUNDER_DMUB; |
| 1279 | break; | 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 | default: | 1328 | default: |
| 1283 | /* ASIC doesn't support DMUB. */ | 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 | static const struct drm_mode_config_funcs amdgpu_dm_mode_funcs = { | 2142 | static const struct drm_mode_config_funcs amdgpu_dm_mode_funcs = { |
| 2097 | .fb_create = amdgpu_display_user_framebuffer_create, | 2143 | .fb_create = amdgpu_display_user_framebuffer_create, |
| 2144 | .get_format_info = amd_get_format_info, | ||
| 2098 | .output_poll_changed = drm_fb_helper_output_poll_changed, | 2145 | .output_poll_changed = drm_fb_helper_output_poll_changed, |
| 2099 | .atomic_check = amdgpu_dm_atomic_check, | 2146 | .atomic_check = amdgpu_dm_atomic_check, |
| 2100 | .atomic_commit = amdgpu_dm_atomic_commit, | 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 | case CHIP_NAVI10: | 3443 | case CHIP_NAVI10: |
| 3397 | case CHIP_NAVI14: | 3444 | case CHIP_NAVI14: |
| 3398 | case CHIP_RENOIR: | 3445 | case CHIP_RENOIR: |
| 3399 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 3400 | case CHIP_SIENNA_CICHLID: | 3446 | case CHIP_SIENNA_CICHLID: |
| 3401 | case CHIP_NAVY_FLOUNDER: | 3447 | case CHIP_NAVY_FLOUNDER: |
| 3402 | #endif | 3448 | case CHIP_DIMGREY_CAVEFISH: |
| 3449 | case CHIP_VANGOGH: | ||
| 3403 | if (dcn10_register_irq_handlers(dm->adev)) { | 3450 | if (dcn10_register_irq_handlers(dm->adev)) { |
| 3404 | DRM_ERROR("DM: Failed to initialize IRQ\n"); | 3451 | DRM_ERROR("DM: Failed to initialize IRQ\n"); |
| 3405 | goto fail; | 3452 | goto fail; |
| @@ -3558,31 +3605,27 @@ static int dm_early_init(void *handle) · 152 unmodified lines | |||
| 3558 | break; | 3605 | break; |
| 3559 | #if defined(CONFIG_DRM_AMD_DC_DCN) | 3606 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| 3560 | case CHIP_RAVEN: | 3607 | case CHIP_RAVEN: |
| 3608 | case CHIP_RENOIR: | ||
| 3609 | case CHIP_VANGOGH: | ||
| 3561 | adev->mode_info.num_crtc = 4; | 3610 | adev->mode_info.num_crtc = 4; |
| 3562 | adev->mode_info.num_hpd = 4; | 3611 | adev->mode_info.num_hpd = 4; |
| 3563 | adev->mode_info.num_dig = 4; | 3612 | adev->mode_info.num_dig = 4; |
| 3564 | break; | 3613 | break; |
| 3565 | #endif | ||
| 3566 | case CHIP_NAVI10: | 3614 | case CHIP_NAVI10: |
| 3567 | case CHIP_NAVI12: | 3615 | case CHIP_NAVI12: |
| 3568 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 3569 | case CHIP_SIENNA_CICHLID: | 3616 | case CHIP_SIENNA_CICHLID: |
| 3570 | case CHIP_NAVY_FLOUNDER: | 3617 | case CHIP_NAVY_FLOUNDER: |
| 3571 | #endif | ||
| 3572 | adev->mode_info.num_crtc = 6; | 3618 | adev->mode_info.num_crtc = 6; |
| 3573 | adev->mode_info.num_hpd = 6; | 3619 | adev->mode_info.num_hpd = 6; |
| 3574 | adev->mode_info.num_dig = 6; | 3620 | adev->mode_info.num_dig = 6; |
| 3575 | break; | 3621 | break; |
| 3576 | case CHIP_NAVI14: | 3622 | case CHIP_NAVI14: |
| 3623 | case CHIP_DIMGREY_CAVEFISH: | ||
| 3577 | adev->mode_info.num_crtc = 5; | 3624 | adev->mode_info.num_crtc = 5; |
| 3578 | adev->mode_info.num_hpd = 5; | 3625 | adev->mode_info.num_hpd = 5; |
| 3579 | adev->mode_info.num_dig = 5; | 3626 | adev->mode_info.num_dig = 5; |
| 3580 | break; | 3627 | break; |
| 3581 | case CHIP_RENOIR: | 3628 | #endif |
| 3582 | adev->mode_info.num_crtc = 4; | ||
| 3583 | adev->mode_info.num_hpd = 4; | ||
| 3584 | adev->mode_info.num_dig = 4; | ||
| 3585 | break; | ||
| 3586 | default: | 3629 | default: |
| 3587 | DRM_ERROR("Unsupported ASIC type: 0x%X\n", adev->asic_type); | 3630 | DRM_ERROR("Unsupported ASIC type: 0x%X\n", adev->asic_type); |
| 3588 | return -EINVAL; | 3631 | return -EINVAL; |
| @@ -3686,78 +3729,84 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state, · 97 unmodified lines | |||
| 3686 | return 0; | 3729 | return 0; |
| 3687 | } | 3730 | } |
| 3688 | 3731 | ||
| 3689 | static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb, | 3732 | static void |
| 3690 | uint64_t *tiling_flags, bool *tmz_surface) | 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; | 3736 | /* Fill GFX8 params */ |
| 3693 | int r; | 3737 | if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == DC_ARRAY_2D_TILED_THIN1) { |
| 3694 | 3738 | unsigned int bankw, bankh, mtaspect, tile_split, num_banks; | |
| 3695 | if (!amdgpu_fb) { | ||
| 3696 | *tiling_flags = 0; | ||
| 3697 | *tmz_surface = false; | ||
| 3698 | return 0; | ||
| 3699 | } | ||
| 3700 | 3739 | ||
| 3701 | rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]); | 3740 | bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH); |
| 3702 | r = amdgpu_bo_reserve(rbo, false); | 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)) { | 3746 | /* XXX fix me for VI */ |
| 3705 | /* Don't show error message when returning -ERESTARTSYS */ | 3747 | tiling_info->gfx8.num_banks = num_banks; |
| 3706 | if (r != -ERESTARTSYS) | 3748 | tiling_info->gfx8.array_mode = |
| 3707 | DRM_ERROR("Unable to reserve buffer: %d\n", r); | 3749 | DC_ARRAY_2D_TILED_THIN1; |
| 3708 | return r; | 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) | 3761 | tiling_info->gfx8.pipe_config = |
| 3712 | amdgpu_bo_get_tiling_flags(rbo, tiling_flags); | 3762 | AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG); |
| 3713 | |||
| 3714 | if (tmz_surface) | ||
| 3715 | *tmz_surface = amdgpu_bo_encrypted(rbo); | ||
| 3716 | |||
| 3717 | amdgpu_bo_unreserve(rbo); | ||
| 3718 | |||
| 3719 | return r; | ||
| 3720 | } | 3763 | } |
| 3721 | 3764 | ||
| 3722 | static inline uint64_t get_dcc_address(uint64_t address, uint64_t tiling_flags) | 3765 | static void |
| 3723 | { | 3766 | fill_gfx9_tiling_info_from_device(const struct amdgpu_device *adev, |
| 3724 | uint32_t offset = AMDGPU_TILING_GET(tiling_flags, DCC_OFFSET_256B); | 3767 | union dc_tiling_info *tiling_info) |
| 3725 | 3768 | { | |
| 3726 | return offset ? (address + offset * 256) : 0; | 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 | static int | 3789 | static int |
| 3730 | fill_plane_dcc_attributes(struct amdgpu_device *adev, | 3790 | validate_dcc(struct amdgpu_device *adev, |
| 3731 | const struct amdgpu_framebuffer *afb, | 3791 | const enum surface_pixel_format format, |
| 3732 | const enum surface_pixel_format format, | 3792 | const enum dc_rotation_angle rotation, |
| 3733 | const enum dc_rotation_angle rotation, | 3793 | const union dc_tiling_info *tiling_info, |
| 3734 | const struct plane_size *plane_size, | 3794 | const struct dc_plane_dcc_param *dcc, |
| 3735 | const union dc_tiling_info *tiling_info, | 3795 | const struct dc_plane_address *address, |
| 3736 | const uint64_t info, | 3796 | const struct plane_size *plane_size) |
| 3737 | struct dc_plane_dcc_param *dcc, | ||
| 3738 | struct dc_plane_address *address, | ||
| 3739 | bool force_disable_dcc) | ||
| 3740 | { | 3797 | { |
| 3741 | struct dc *dc = adev->dm.dc; | 3798 | struct dc *dc = adev->dm.dc; |
| 3742 | struct dc_dcc_surface_param input; | 3799 | struct dc_dcc_surface_param input; |
| 3743 | struct dc_surface_dcc_cap output; | 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 | memset(&input, 0, sizeof(input)); | 3802 | memset(&input, 0, sizeof(input)); |
| 3749 | memset(&output, 0, sizeof(output)); | 3803 | memset(&output, 0, sizeof(output)); |
| 3750 | 3804 | ||
| 3751 | if (force_disable_dcc) | 3805 | if (!dcc->enable) |
| 3752 | return 0; | 3806 | return 0; |
| 3753 | 3807 | ||
| 3754 | if (!offset) | 3808 | if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || |
| 3755 | return 0; | 3809 | !dc->cap_funcs.get_dcc_compression_cap) |
| 3756 | |||
| 3757 | if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) | ||
| 3758 | return 0; | ||
| 3759 | |||
| 3760 | if (!dc->cap_funcs.get_dcc_compression_cap) | ||
| 3761 | return -EINVAL; | 3810 | return -EINVAL; |
| 3762 | 3811 | ||
| 3763 | input.format = format; | 3812 | input.format = format; |
| @@ -3776,17 +3825,508 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev, · 12 unmodified lines | |||
| 3776 | if (!output.capable) | 3825 | if (!output.capable) |
| 3777 | return -EINVAL; | 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 | return -EINVAL; | 3830 | return -EINVAL; |
| 3781 | 3831 | ||
| 3782 | dcc->enable = 1; | 3832 | return 0; |
| 3783 | dcc->meta_pitch = | 3833 | } |
| 3784 | AMDGPU_TILING_GET(info, DCC_PITCH_MAX) + 1; | 3834 | |
| 3785 | dcc->independent_64b_blks = i64b; | 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); | 3934 | if (AMD_FMT_MOD_GET(DCC, modifier)) |
| 3788 | address->grph.meta_addr.low_part = lower_32_bits(dcc_address); | 3935 | return lookup_format_info(dcc_formats, ARRAY_SIZE(dcc_formats), |
| 3789 | address->grph.meta_addr.high_part = upper_32_bits(dcc_address); | 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 | return 0; | 4331 | return 0; |
| 3792 | } | 4332 | } |
| @@ -3815,6 +4355,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, · 22 unmodified lines | |||
| 3815 | address->tmz_surface = tmz_surface; | 4355 | address->tmz_surface = tmz_surface; |
| 3816 | 4356 | ||
| 3817 | if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { | 4357 | if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { |
| 4358 | uint64_t addr = afb->address + fb->offsets[0]; | ||
| 4359 | |||
| 3818 | plane_size->surface_size.x = 0; | 4360 | plane_size->surface_size.x = 0; |
| 3819 | plane_size->surface_size.y = 0; | 4361 | plane_size->surface_size.y = 0; |
| 3820 | plane_size->surface_size.width = fb->width; | 4362 | plane_size->surface_size.width = fb->width; |
| @@ -3823,9 +4365,10 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, · 2 unmodified lines | |||
| 3823 | fb->pitches[0] / fb->format->cpp[0]; | 4365 | fb->pitches[0] / fb->format->cpp[0]; |
| 3824 | 4366 | ||
| 3825 | address->type = PLN_ADDR_TYPE_GRAPHICS; | 4367 | address->type = PLN_ADDR_TYPE_GRAPHICS; |
| 3826 | address->grph.addr.low_part = lower_32_bits(afb->address); | 4368 | address->grph.addr.low_part = lower_32_bits(addr); |
| 3827 | address->grph.addr.high_part = upper_32_bits(afb->address); | 4369 | address->grph.addr.high_part = upper_32_bits(addr); |
| 3828 | } else if (format < SURFACE_PIXEL_FORMAT_INVALID) { | 4370 | } else if (format < SURFACE_PIXEL_FORMAT_INVALID) { |
| 4371 | uint64_t luma_addr = afb->address + fb->offsets[0]; | ||
| 3829 | uint64_t chroma_addr = afb->address + fb->offsets[1]; | 4372 | uint64_t chroma_addr = afb->address + fb->offsets[1]; |
| 3830 | 4373 | ||
| 3831 | plane_size->surface_size.x = 0; | 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 | address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE; | 4390 | address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE; |
| 3848 | address->video_progressive.luma_addr.low_part = | 4391 | address->video_progressive.luma_addr.low_part = |
| 3849 | lower_32_bits(afb->address); | 4392 | lower_32_bits(luma_addr); |
| 3850 | address->video_progressive.luma_addr.high_part = | 4393 | address->video_progressive.luma_addr.high_part = |
| 3851 | upper_32_bits(afb->address); | 4394 | upper_32_bits(luma_addr); |
| 3852 | address->video_progressive.chroma_addr.low_part = | 4395 | address->video_progressive.chroma_addr.low_part = |
| 3853 | lower_32_bits(chroma_addr); | 4396 | lower_32_bits(chroma_addr); |
| 3854 | address->video_progressive.chroma_addr.high_part = | 4397 | address->video_progressive.chroma_addr.high_part = |
| 3855 | upper_32_bits(chroma_addr); | 4398 | upper_32_bits(chroma_addr); |
| 3856 | } | 4399 | } |
| 3857 | 4400 | ||
| 3858 | /* Fill GFX8 params */ | 4401 | if (adev->family >= AMDGPU_FAMILY_AI) { |
| 3859 | if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == DC_ARRAY_2D_TILED_THIN1) { | 4402 | ret = fill_gfx9_plane_attributes_from_modifiers(adev, afb, format, |
| 3860 | unsigned int bankw, bankh, mtaspect, tile_split, num_banks; | 4403 | rotation, plane_size, |
| 3861 | 4404 | tiling_info, dcc, | |
| 3862 | bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH); | 4405 | address, |
| 3863 | bankh = AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT); | 4406 | force_disable_dcc); |
| 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); | ||
| 3924 | if (ret) | 4407 | if (ret) |
| 3925 | return ret; | 4408 | return ret; |
| 4409 | } else { | ||
| 4410 | fill_gfx8_tiling_info_from_flags(tiling_info, tiling_flags); | ||
| 3926 | } | 4411 | } |
| 3927 | 4412 | ||
| 3928 | return 0; | 4413 | return 0; |
| @@ -4122,7 +4607,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, · 193 unmodified lines | |||
| 4122 | struct drm_crtc_state *crtc_state) | 4607 | struct drm_crtc_state *crtc_state) |
| 4123 | { | 4608 | { |
| 4124 | struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state); | 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 | struct dc_scaling_info scaling_info; | 4611 | struct dc_scaling_info scaling_info; |
| 4127 | struct dc_plane_info plane_info; | 4612 | struct dc_plane_info plane_info; |
| 4128 | int ret; | 4613 | int ret; |
| @@ -4139,10 +4624,10 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, · 10 unmodified lines | |||
| 4139 | 4624 | ||
| 4140 | force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend; | 4625 | force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend; |
| 4141 | ret = fill_dc_plane_info_and_addr(adev, plane_state, | 4626 | ret = fill_dc_plane_info_and_addr(adev, plane_state, |
| 4142 | dm_plane_state->tiling_flags, | 4627 | afb->tiling_flags, |
| 4143 | &plane_info, | 4628 | &plane_info, |
| 4144 | &dc_plane_state->address, | 4629 | &dc_plane_state->address, |
| 4145 | dm_plane_state->tmz_surface, | 4630 | afb->tmz_surface, |
| 4146 | force_disable_dcc); | 4631 | force_disable_dcc); |
| 4147 | if (ret) | 4632 | if (ret) |
| 4148 | return ret; | 4633 | return ret; |
| @@ -4732,6 +5217,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, · 583 unmodified lines | |||
| 4732 | if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0], | 5217 | if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0], |
| 4733 | &dsc_caps, | 5218 | &dsc_caps, |
| 4734 | aconnector->dc_link->ctx->dc->debug.dsc_min_slice_height_override, | 5219 | aconnector->dc_link->ctx->dc->debug.dsc_min_slice_height_override, |
| 5220 | 0, | ||
| 4735 | link_bandwidth_kbps, | 5221 | link_bandwidth_kbps, |
| 4736 | &stream->timing, | 5222 | &stream->timing, |
| 4737 | &stream->timing.dsc_cfg)) | 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 | dc_sink = to_amdgpu_dm_connector(connector)->dc_sink; | 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 | DRM_ERROR("dc_sink is NULL!\n"); | 5801 | DRM_ERROR("dc_sink is NULL!\n"); |
| 5315 | goto fail; | 5802 | goto fail; |
| 5316 | } | 5803 | } |
| @@ -5416,6 +5903,8 @@ amdgpu_dm_connector_atomic_check(struct drm_connector *conn, · 99 unmodified lines | |||
| 5416 | struct drm_crtc_state *new_crtc_state; | 5903 | struct drm_crtc_state *new_crtc_state; |
| 5417 | int ret; | 5904 | int ret; |
| 5418 | 5905 | ||
| 5906 | trace_amdgpu_dm_connector_atomic_check(new_con_state); | ||
| 5907 | |||
| 5419 | if (!crtc) | 5908 | if (!crtc) |
| 5420 | return 0; | 5909 | return 0; |
| 5421 | 5910 | ||
| @@ -5523,6 +6012,8 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc, · 101 unmodified lines | |||
| 5523 | struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state); | 6012 | struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state); |
| 5524 | int ret = -EINVAL; | 6013 | int ret = -EINVAL; |
| 5525 | 6014 | ||
| 6015 | trace_amdgpu_dm_crtc_atomic_check(crtc_state); | ||
| 6016 | |||
| 5526 | dm_update_crtc_active_planes(crtc, crtc_state); | 6017 | dm_update_crtc_active_planes(crtc, crtc_state); |
| 5527 | 6018 | ||
| 5528 | if (unlikely(!dm_crtc_state->stream && | 6019 | if (unlikely(!dm_crtc_state->stream && |
| @@ -5739,10 +6230,6 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane) · 210 unmodified lines | |||
| 5739 | dc_plane_state_retain(dm_plane_state->dc_state); | 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 | return &dm_plane_state->base; | 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 | .reset = dm_drm_plane_reset, | 6251 | .reset = dm_drm_plane_reset, |
| 5765 | .atomic_duplicate_state = dm_drm_plane_duplicate_state, | 6252 | .atomic_duplicate_state = dm_drm_plane_duplicate_state, |
| 5766 | .atomic_destroy_state = dm_drm_plane_destroy_state, | 6253 | .atomic_destroy_state = dm_drm_plane_destroy_state, |
| 6254 | .format_mod_supported = dm_plane_format_mod_supported, | ||
| 5767 | }; | 6255 | }; |
| 5768 | 6256 | ||
| 5769 | static int dm_plane_helper_prepare_fb(struct drm_plane *plane, | 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 | fill_plane_buffer_attributes( | 6336 | fill_plane_buffer_attributes( |
| 5849 | adev, afb, plane_state->format, plane_state->rotation, | 6337 | adev, afb, plane_state->format, plane_state->rotation, |
| 5850 | dm_plane_state_new->tiling_flags, | 6338 | afb->tiling_flags, |
| 5851 | &plane_state->tiling_info, &plane_state->plane_size, | 6339 | &plane_state->tiling_info, &plane_state->plane_size, |
| 5852 | &plane_state->dcc, &plane_state->address, | 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 | return 0; | 6344 | return 0; |
| @@ -5898,6 +6386,8 @@ static int dm_plane_atomic_check(struct drm_plane *plane, · 41 unmodified lines | |||
| 5898 | struct drm_crtc_state *new_crtc_state; | 6386 | struct drm_crtc_state *new_crtc_state; |
| 5899 | int ret; | 6387 | int ret; |
| 5900 | 6388 | ||
| 6389 | trace_amdgpu_dm_plane_atomic_check(state); | ||
| 6390 | |||
| 5901 | dm_plane_state = to_dm_plane_state(state); | 6391 | dm_plane_state = to_dm_plane_state(state); |
| 5902 | 6392 | ||
| 5903 | if (!dm_plane_state->dc_state) | 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 | struct drm_plane_state *old_state = | 6428 | struct drm_plane_state *old_state = |
| 5939 | drm_atomic_get_old_plane_state(new_state->state, plane); | 6429 | drm_atomic_get_old_plane_state(new_state->state, plane); |
| 5940 | 6430 | ||
| 6431 | trace_amdgpu_dm_atomic_update_cursor(new_state); | ||
| 6432 | |||
| 5941 | swap(plane->state->fb, new_state->fb); | 6433 | swap(plane->state->fb, new_state->fb); |
| 5942 | 6434 | ||
| 5943 | plane->state->src_x = new_state->src_x; | 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 | int num_formats; | 6548 | int num_formats; |
| 6057 | int res = -EPERM; | 6549 | int res = -EPERM; |
| 6058 | unsigned int supported_rotations; | 6550 | unsigned int supported_rotations; |
| 6551 | uint64_t *modifiers = NULL; | ||
| 6059 | 6552 | ||
| 6060 | num_formats = get_plane_formats(plane, plane_cap, formats, | 6553 | num_formats = get_plane_formats(plane, plane_cap, formats, |
| 6061 | ARRAY_SIZE(formats)); | 6554 | ARRAY_SIZE(formats)); |
| 6062 | 6555 | ||
| 6556 | res = get_plane_modifiers(dm->adev, plane->type, &modifiers); | ||
| 6557 | if (res) | ||
| 6558 | return res; | ||
| 6559 | |||
| 6063 | res = drm_universal_plane_init(adev_to_drm(dm->adev), plane, possible_crtcs, | 6560 | res = drm_universal_plane_init(adev_to_drm(dm->adev), plane, possible_crtcs, |
| 6064 | &dm_plane_funcs, formats, num_formats, | 6561 | &dm_plane_funcs, formats, num_formats, |
| 6065 | NULL, plane->type, NULL); | 6562 | modifiers, plane->type, NULL); |
| 6563 | kfree(modifiers); | ||
| 6066 | if (res) | 6564 | if (res) |
| 6067 | return res; | 6565 | return res; |
| 6068 | 6566 | ||
| @@ -7109,6 +7607,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, · 1040 unmodified lines | |||
| 7109 | struct drm_crtc *crtc = new_plane_state->crtc; | 7607 | struct drm_crtc *crtc = new_plane_state->crtc; |
| 7110 | struct drm_crtc_state *new_crtc_state; | 7608 | struct drm_crtc_state *new_crtc_state; |
| 7111 | struct drm_framebuffer *fb = new_plane_state->fb; | 7609 | struct drm_framebuffer *fb = new_plane_state->fb; |
| 7610 | struct amdgpu_framebuffer *afb = (struct amdgpu_framebuffer *)fb; | ||
| 7112 | bool plane_needs_flip; | 7611 | bool plane_needs_flip; |
| 7113 | struct dc_plane_state *dc_plane; | 7612 | struct dc_plane_state *dc_plane; |
| 7114 | struct dm_plane_state *dm_new_plane_state = to_dm_plane_state(new_plane_state); | 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 | fill_dc_plane_info_and_addr( | 7663 | fill_dc_plane_info_and_addr( |
| 7165 | dm->adev, new_plane_state, | 7664 | dm->adev, new_plane_state, |
| 7166 | dm_new_plane_state->tiling_flags, | 7665 | afb->tiling_flags, |
| 7167 | &bundle->plane_infos[planes_count], | 7666 | &bundle->plane_infos[planes_count], |
| 7168 | &bundle->flip_addrs[planes_count].address, | 7667 | &bundle->flip_addrs[planes_count].address, |
| 7169 | dm_new_plane_state->tmz_surface, false); | 7668 | afb->tmz_surface, false); |
| 7170 | 7669 | ||
| 7171 | DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n", | 7670 | DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n", |
| 7172 | new_plane_state->plane->index, | 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 | int crtc_disable_count = 0; | 8000 | int crtc_disable_count = 0; |
| 7502 | bool mode_set_reset_required = false; | 8001 | bool mode_set_reset_required = false; |
| 7503 | 8002 | ||
| 8003 | trace_amdgpu_dm_atomic_commit_tail_begin(state); | ||
| 8004 | |||
| 7504 | drm_atomic_helper_update_legacy_modeset_state(dev, state); | 8005 | drm_atomic_helper_update_legacy_modeset_state(dev, state); |
| 7505 | drm_atomic_helper_calc_timestamping_constants(state); | 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 | * TODO: Come up with a more elegant solution for this. | 8807 | * TODO: Come up with a more elegant solution for this. |
| 8307 | */ | 8808 | */ |
| 8308 | for_each_oldnew_plane_in_state(state, other, old_other_state, new_other_state, i) { | 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; | 8810 | struct amdgpu_framebuffer *old_afb, *new_afb; |
| 8310 | |||
| 8311 | if (other->type == DRM_PLANE_TYPE_CURSOR) | 8811 | if (other->type == DRM_PLANE_TYPE_CURSOR) |
| 8312 | continue; | 8812 | continue; |
| 8313 | 8813 | ||
| @@ -8351,12 +8851,12 @@ static bool should_reset_plane(struct drm_atomic_state *state, · 37 unmodified lines | |||
| 8351 | if (old_other_state->fb->format != new_other_state->fb->format) | 8851 | if (old_other_state->fb->format != new_other_state->fb->format) |
| 8352 | return true; | 8852 | return true; |
| 8353 | 8853 | ||
| 8354 | old_dm_plane_state = to_dm_plane_state(old_other_state); | 8854 | old_afb = (struct amdgpu_framebuffer *)old_other_state->fb; |
| 8355 | new_dm_plane_state = to_dm_plane_state(new_other_state); | 8855 | new_afb = (struct amdgpu_framebuffer *)new_other_state->fb; |
| 8356 | 8856 | ||
| 8357 | /* Tiling and DCC changes also require bandwidth updates. */ | 8857 | /* Tiling and DCC changes also require bandwidth updates. */ |
| 8358 | if (old_dm_plane_state->tiling_flags != | 8858 | if (old_afb->tiling_flags != new_afb->tiling_flags || |
| 8359 | new_dm_plane_state->tiling_flags) | 8859 | old_afb->base.modifier != new_afb->base.modifier) |
| 8360 | return true; | 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 | enum dc_status status; | 9087 | enum dc_status status; |
| 8588 | int ret, i; | 9088 | int ret, i; |
| 8589 | bool lock_and_validation_needed = false; | 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 | ret = drm_atomic_helper_check_modeset(dev, state); | 9094 | ret = drm_atomic_helper_check_modeset(dev, state); |
| 8594 | if (ret) | 9095 | if (ret) |
| @@ -8629,9 +9130,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, · 34 unmodified lines | |||
| 8629 | } | 9130 | } |
| 8630 | #endif | 9131 | #endif |
| 8631 | for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { | 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 | if (!drm_atomic_crtc_needs_modeset(new_crtc_state) && | 9135 | if (!drm_atomic_crtc_needs_modeset(new_crtc_state) && |
| 8633 | !new_crtc_state->color_mgmt_changed && | 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 | continue; | 9139 | continue; |
| 8636 | 9140 | ||
| 8637 | if (!new_crtc_state->enable) | 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 | /* Remove exiting planes if they are modified */ | 9189 | /* Remove exiting planes if they are modified */ |
| 8697 | for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) { | 9190 | for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) { |
| 8698 | ret = dm_update_plane_state(dc, state, plane, | 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 | /* Must be success */ | 9380 | /* Must be success */ |
| 8888 | WARN_ON(ret); | 9381 | WARN_ON(ret); |
| 9382 | |||
| 9383 | trace_amdgpu_dm_atomic_check_finish(state, ret); | ||
| 9384 | |||
| 8889 | return ret; | 9385 | return ret; |
| 8890 | 9386 | ||
| 8891 | fail: | 9387 | fail: |
| @@ -8896,6 +9392,8 @@ fail: · 4 unmodified lines | |||
| 8896 | else | 9392 | else |
| 8897 | DRM_DEBUG_DRIVER("Atomic check failed with err: %d \n", ret); | 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 | return ret; | 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 | mutex_unlock(&adev->dm.dc_lock); | 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 | * @bo_ptr: Pointer to the buffer object | 86 | * @bo_ptr: Pointer to the buffer object |
| 87 | * @gpu_addr: MMIO gpu addr | 87 | * @gpu_addr: MMIO gpu addr |
| 88 | */ | 88 | */ |
| 89 | struct dm_comressor_info { | 89 | struct dm_compressor_info { |
| 90 | void *cpu_addr; | 90 | void *cpu_addr; |
| 91 | struct amdgpu_bo *bo_ptr; | 91 | struct amdgpu_bo *bo_ptr; |
| 92 | uint64_t gpu_addr; | 92 | uint64_t gpu_addr; |
| @@ -148,7 +148,7 @@ struct amdgpu_dm_backlight_caps { · 55 unmodified lines | |||
| 148 | * @soc_bounding_box: SOC bounding box values provided by gpu_info FW | 148 | * @soc_bounding_box: SOC bounding box values provided by gpu_info FW |
| 149 | * @cached_state: Caches device atomic state for suspend/resume | 149 | * @cached_state: Caches device atomic state for suspend/resume |
| 150 | * @cached_dc_state: Cached state of content streams | 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 | * @force_timing_sync: set via debugfs. When set, indicates that all connected | 152 | * @force_timing_sync: set via debugfs. When set, indicates that all connected |
| 153 | * displays will be forced to synchronize. | 153 | * displays will be forced to synchronize. |
| 154 | */ | 154 | */ |
| @@ -324,7 +324,7 @@ struct amdgpu_display_manager { · 169 unmodified lines | |||
| 324 | struct drm_atomic_state *cached_state; | 324 | struct drm_atomic_state *cached_state; |
| 325 | struct dc_state *cached_dc_state; | 325 | struct dc_state *cached_dc_state; |
| 326 | 326 | ||
| 327 | struct dm_comressor_info compressor; | 327 | struct dm_compressor_info compressor; |
| 328 | 328 | ||
| 329 | const struct firmware *fw_dmcu; | 329 | const struct firmware *fw_dmcu; |
| 330 | uint32_t dmcu_fw_version; | 330 | uint32_t dmcu_fw_version; |
| @@ -420,8 +420,6 @@ struct dc_plane_state; · 89 unmodified lines | |||
| 420 | struct dm_plane_state { | 420 | struct dm_plane_state { |
| 421 | struct drm_plane_state base; | 421 | struct drm_plane_state base; |
| 422 | struct dc_plane_state *dc_state; | 422 | struct dc_plane_state *dc_state; |
| 423 | uint64_t tiling_flags; | ||
| 424 | bool tmz_surface; | ||
| 425 | }; | 423 | }; |
| 426 | 424 | ||
| 427 | struct dm_crtc_state { | 425 | struct dm_crtc_state { |
| @@ -440,6 +438,7 @@ struct dm_crtc_state { · 12 unmodified lines | |||
| 440 | bool freesync_timing_changed; | 438 | bool freesync_timing_changed; |
| 441 | bool freesync_vrr_info_changed; | 439 | bool freesync_vrr_info_changed; |
| 442 | 440 | ||
| 441 | bool dsc_force_changed; | ||
| 443 | bool vrr_supported; | 442 | bool vrr_supported; |
| 444 | struct mod_freesync_config freesync_config; | 443 | struct mod_freesync_config freesync_config; |
| 445 | struct dc_info_packet vrr_infopacket; | 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 | /* Enable CRTC CRC generation if necessary. */ | 115 | /* Enable CRTC CRC generation if necessary. */ |
| 116 | if (dm_is_crc_source_crtc(source)) { | 116 | if (dm_is_crc_source_crtc(source)) { |
| 117 | if (!dc_stream_configure_crc(stream_state->ctx->dc, | 117 | if (!dc_stream_configure_crc(stream_state->ctx->dc, |
| 118 | stream_state, enable, enable)) { | 118 | stream_state, NULL, enable, enable)) { |
| 119 | ret = -EINVAL; | 119 | ret = -EINVAL; |
| 120 | goto unlock; | 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 | bool disable_hpd = false; | 556 | bool disable_hpd = false; |
| 557 | bool valid_test_pattern = false; | 557 | bool valid_test_pattern = false; |
| 558 | uint8_t param_nums = 0; | 558 | uint8_t param_nums = 0; |
| 559 | /* init with defalut 80bit custom pattern */ | 559 | /* init with default 80bit custom pattern */ |
| 560 | uint8_t custom_pattern[10] = { | 560 | uint8_t custom_pattern[10] = { |
| 561 | 0x1f, 0x7c, 0xf0, 0xc1, 0x07, | 561 | 0x1f, 0x7c, 0xf0, 0xc1, 0x07, |
| 562 | 0x1f, 0x7c, 0xf0, 0xc1, 0x07 | 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 | size_t size, loff_t *pos) | 1253 | size_t size, loff_t *pos) |
| 1254 | { | 1254 | { |
| 1255 | struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; | 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 | struct pipe_ctx *pipe_ctx; | 1260 | struct pipe_ctx *pipe_ctx; |
| 1257 | int i; | 1261 | int i; |
| 1258 | char *wr_buf = NULL; | 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 | if (!pipe_ctx || !pipe_ctx->stream) | 1299 | if (!pipe_ctx || !pipe_ctx->stream) |
| 1296 | goto done; | 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 | if (param[0] == 1) | 1321 | if (param[0] == 1) |
| 1299 | aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_ENABLE; | 1322 | aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_ENABLE; |
| 1300 | else if (param[0] == 2) | 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 | else | 1325 | else |
| 1303 | aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_DEFAULT; | 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 | done: | 1336 | done: |
| 1306 | kfree(wr_buf); | 1337 | kfree(wr_buf); |
| 1307 | return size; | 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 | struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; | 1440 | struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; |
| 1410 | struct pipe_ctx *pipe_ctx; | 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 | int i; | 1446 | int i; |
| 1412 | char *wr_buf = NULL; | 1447 | char *wr_buf = NULL; |
| 1413 | uint32_t wr_buf_size = 42; | 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 | if (!pipe_ctx || !pipe_ctx->stream) | 1484 | if (!pipe_ctx || !pipe_ctx->stream) |
| 1450 | goto done; | 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 | if (param[0] > 0) | 1506 | if (param[0] > 0) |
| 1453 | aconnector->dsc_settings.dsc_num_slices_h = DIV_ROUND_UP( | 1507 | aconnector->dsc_settings.dsc_num_slices_h = DIV_ROUND_UP( |
| 1454 | pipe_ctx->stream->timing.h_addressable, | 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 | else | 1510 | else |
| 1457 | aconnector->dsc_settings.dsc_num_slices_h = 0; | 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 | done: | 1521 | done: |
| 1460 | kfree(wr_buf); | 1522 | kfree(wr_buf); |
| 1461 | return size; | 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 | size_t size, loff_t *pos) | 1623 | size_t size, loff_t *pos) |
| 1562 | { | 1624 | { |
| 1563 | struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; | 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 | struct pipe_ctx *pipe_ctx; | 1630 | struct pipe_ctx *pipe_ctx; |
| 1565 | int i; | 1631 | int i; |
| 1566 | char *wr_buf = NULL; | 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 | if (!pipe_ctx || !pipe_ctx->stream) | 1669 | if (!pipe_ctx || !pipe_ctx->stream) |
| 1604 | goto done; | 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 | if (param[0] > 0) | 1691 | if (param[0] > 0) |
| 1607 | aconnector->dsc_settings.dsc_num_slices_v = DIV_ROUND_UP( | 1692 | aconnector->dsc_settings.dsc_num_slices_v = DIV_ROUND_UP( |
| 1608 | pipe_ctx->stream->timing.v_addressable, | 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 | else | 1695 | else |
| 1611 | aconnector->dsc_settings.dsc_num_slices_v = 0; | 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 | done: | 1706 | done: |
| 1614 | kfree(wr_buf); | 1707 | kfree(wr_buf); |
| 1615 | return size; | 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 | size_t size, loff_t *pos) | 1801 | size_t size, loff_t *pos) |
| 1709 | { | 1802 | { |
| 1710 | struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; | 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 | struct pipe_ctx *pipe_ctx; | 1808 | struct pipe_ctx *pipe_ctx; |
| 1712 | int i; | 1809 | int i; |
| 1713 | char *wr_buf = NULL; | 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 | if (!pipe_ctx || !pipe_ctx->stream) | 1847 | if (!pipe_ctx || !pipe_ctx->stream) |
| 1751 | goto done; | 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 | aconnector->dsc_settings.dsc_bits_per_pixel = param[0]; | 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 | done: | 1879 | done: |
| 1756 | kfree(wr_buf); | 1880 | kfree(wr_buf); |
| 1757 | return size; | 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 | /* TODO: something */ | 628 | /* TODO: something */ |
| 629 | } | 629 | } |
| 630 | #ifdef CONFIG_DRM_AMD_DC_DCN3_0 | ||
| 631 | 630 | ||
| 632 | void *dm_helpers_allocate_gpu_mem( | 631 | void *dm_helpers_allocate_gpu_mem( |
| 633 | struct dc_context *ctx, | 632 | struct dc_context *ctx, |
| @@ -646,4 +645,3 @@ void dm_helpers_free_gpu_mem( · 12 unmodified lines | |||
| 646 | { | 645 | { |
| 647 | // TODO | 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 | ¶ms[i].sink->dsc_caps.dsc_dec_caps, | 500 | ¶ms[i].sink->dsc_caps.dsc_dec_caps, |
| 501 | params[i].sink->ctx->dc->debug.dsc_min_slice_height_override, | 501 | params[i].sink->ctx->dc->debug.dsc_min_slice_height_override, |
| 502 | 0, | 502 | 0, |
| 503 | 0, | ||
| 503 | params[i].timing, | 504 | params[i].timing, |
| 504 | ¶ms[i].timing->dsc_cfg)) { | 505 | ¶ms[i].timing->dsc_cfg)) { |
| 505 | params[i].timing->flags.DSC = 1; | 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 | param.sink->ctx->dc->res_pool->dscs[0], | 531 | param.sink->ctx->dc->res_pool->dscs[0], |
| 531 | ¶m.sink->dsc_caps.dsc_dec_caps, | 532 | ¶m.sink->dsc_caps.dsc_dec_caps, |
| 532 | param.sink->ctx->dc->debug.dsc_min_slice_height_override, | 533 | param.sink->ctx->dc->debug.dsc_min_slice_height_override, |
| 534 | 0, | ||
| 533 | (int) kbps, param.timing, &dsc_config); | 535 | (int) kbps, param.timing, &dsc_config); |
| 534 | 536 | ||
| 535 | return dsc_config.bits_per_pixel; | 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 | params[count].num_slices_v = aconnector->dsc_settings.dsc_num_slices_v; | 736 | params[count].num_slices_v = aconnector->dsc_settings.dsc_num_slices_v; |
| 735 | params[count].bpp_overwrite = aconnector->dsc_settings.dsc_bits_per_pixel; | 737 | params[count].bpp_overwrite = aconnector->dsc_settings.dsc_bits_per_pixel; |
| 736 | params[count].compression_possible = stream->sink->dsc_caps.dsc_dec_caps.is_dsc_supported; | 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 | if (!dc_dsc_compute_bandwidth_range( | 740 | if (!dc_dsc_compute_bandwidth_range( |
| 739 | stream->sink->ctx->dc->res_pool->dscs[0], | 741 | stream->sink->ctx->dc->res_pool->dscs[0], |
| 740 | stream->sink->ctx->dc->debug.dsc_min_slice_height_override, | 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 | get_default_clock_levels(clk_type, dc_clks); | 346 | get_default_clock_levels(clk_type, dc_clks); |
| 347 | return true; | 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 | pp_to_dc_clock_levels(&pp_clks, dc_clks, clk_type); | 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 | validation_clks.memory_max_clock = 80000; | 359 | validation_clks.memory_max_clock = 80000; |
| 367 | validation_clks.level = 0; | 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 | DRM_INFO("DM_PPLIB: Validation clocks:\n"); | 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 | &pp_clk_info); | 447 | &pp_clk_info); |
| 462 | if (ret) | 448 | if (ret) |
| 463 | return false; | 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 | pp_to_dc_clock_levels_with_voltage(&pp_clk_info, clk_level_info, clk_type); | 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 | const struct dc_context *ctx, | 458 | const struct dc_context *ctx, |
| 478 | struct dm_pp_wm_sets_with_clock_ranges *wm_with_clock_ranges) | 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 | return false; | 476 | return false; |
| 482 | } | 477 | } |
| 483 | 478 | ||
| @@ -528,8 +523,6 @@ bool dm_pp_get_static_clocks( · 44 unmodified lines | |||
| 528 | ret = adev->powerplay.pp_funcs->get_current_clocks( | 523 | ret = adev->powerplay.pp_funcs->get_current_clocks( |
| 529 | adev->powerplay.pp_handle, | 524 | adev->powerplay.pp_handle, |
| 530 | &pp_clk_info); | 525 | &pp_clk_info); |
| 531 | else if (adev->smu.ppt_funcs) | ||
| 532 | ret = smu_get_current_clocks(&adev->smu, &pp_clk_info); | ||
| 533 | else | 526 | else |
| 534 | return false; | 527 | return false; |
| 535 | if (ret) | 528 | if (ret) |
| @@ -603,8 +596,6 @@ void pp_rv_set_pme_wa_enable(struct pp_smu *pp) · 67 unmodified lines | |||
| 603 | 596 | ||
| 604 | if (pp_funcs && pp_funcs->notify_smu_enable_pwe) | 597 | if (pp_funcs && pp_funcs->notify_smu_enable_pwe) |
| 605 | pp_funcs->notify_smu_enable_pwe(pp_handle); | 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 | void pp_rv_set_active_display_count(struct pp_smu *pp, int count) | 601 | void pp_rv_set_active_display_count(struct pp_smu *pp, int count) |
| @@ -33,18 +33,23 @@ · 32 unmodified lines | |||
| 33 | #include "amdgpu_dm.h" | 33 | #include "amdgpu_dm.h" |
| 34 | #include "amdgpu_dm_irq.h" | 34 | #include "amdgpu_dm_irq.h" |
| 35 | #include "amdgpu_pm.h" | 35 | #include "amdgpu_pm.h" |
| 36 | #include "amdgpu_dm_trace.h" | ||
| 36 | 37 | ||
| 37 | 38 | unsigned long long | |
| 38 | 39 | dm_get_elapse_time_in_ns(struct dc_context *ctx, | |
| 39 | unsigned long long dm_get_elapse_time_in_ns(struct dc_context *ctx, | 40 | unsigned long long current_time_stamp, |
| 40 | unsigned long long current_time_stamp, | 41 | unsigned long long last_time_stamp) |
| 41 | unsigned long long last_time_stamp) | ||
| 42 | { | 42 | { |
| 43 | return current_time_stamp - last_time_stamp; | 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 | /**** power component interfaces ****/ | 55 | /**** power component interfaces ****/ |
| @@ -26,45 +26,46 @@ · 25 unmodified lines | |||
| 26 | #undef TRACE_SYSTEM | 26 | #undef TRACE_SYSTEM |
| 27 | #define TRACE_SYSTEM amdgpu_dm | 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 | #define _AMDGPU_DM_TRACE_H_ | 30 | #define _AMDGPU_DM_TRACE_H_ |
| 31 | 31 | ||
| 32 | #include <linux/tracepoint.h> | 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, | 40 | #include "dc/inc/core_types.h" |
| 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 | ); | ||
| 50 | 41 | ||
| 51 | TRACE_EVENT(amdgpu_dc_wreg, | 42 | DECLARE_EVENT_CLASS(amdgpu_dc_reg_template, |
| 52 | TP_PROTO(unsigned long *write_count, uint32_t reg, uint32_t value), | 43 | TP_PROTO(unsigned long *count, uint32_t reg, uint32_t value), |
| 53 | TP_ARGS(write_count, reg, value), | 44 | TP_ARGS(count, reg, value), |
| 54 | TP_STRUCT__entry( | 45 | |
| 55 | __field(uint32_t, reg) | 46 | TP_STRUCT__entry( |
| 56 | __field(uint32_t, value) | 47 | __field(uint32_t, reg) |
| 57 | ), | 48 | __field(uint32_t, value) |
| 58 | TP_fast_assign( | 49 | ), |
| 59 | __entry->reg = reg; | 50 | |
| 60 | __entry->value = value; | 51 | TP_fast_assign( |
| 61 | *write_count = *write_count + 1; | 52 | __entry->reg = reg; |
| 62 | ), | 53 | __entry->value = value; |
| 63 | TP_printk("reg=0x%08lx, value=0x%08lx", | 54 | *count = *count + 1; |
| 64 | (unsigned long)__entry->reg, | 55 | ), |
| 65 | (unsigned long)__entry->value) | 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 | TRACE_EVENT(amdgpu_dc_performance, | 70 | TRACE_EVENT(amdgpu_dc_performance, |
| 70 | TP_PROTO(unsigned long read_count, unsigned long write_count, | 71 | TP_PROTO(unsigned long read_count, unsigned long write_count, |
| @@ -96,6 +97,506 @@ TRACE_EVENT(amdgpu_dc_performance, · 25 unmodified lines | |||
| 96 | (unsigned long)__entry->write_delta, | 97 | (unsigned long)__entry->write_delta, |
| 97 | (unsigned long)__entry->writes) | 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 | #endif /* _AMDGPU_DM_TRACE_H_ */ | 600 | #endif /* _AMDGPU_DM_TRACE_H_ */ |
| 100 | 601 | ||
| 101 | #undef TRACE_INCLUDE_PATH | 602 | #undef TRACE_INCLUDE_PATH |
| @@ -30,10 +30,9 @@ DC_LIBS += dcn20 · 29 unmodified lines | |||
| 30 | DC_LIBS += dsc | 30 | DC_LIBS += dsc |
| 31 | DC_LIBS += dcn10 dml | 31 | DC_LIBS += dcn10 dml |
| 32 | DC_LIBS += dcn21 | 32 | DC_LIBS += dcn21 |
| 33 | endif | ||
| 34 | |||
| 35 | ifdef CONFIG_DRM_AMD_DC_DCN3_0 | ||
| 36 | DC_LIBS += dcn30 | 33 | DC_LIBS += dcn30 |
| 34 | DC_LIBS += dcn301 | ||
| 35 | DC_LIBS += dcn302 | ||
| 37 | endif | 36 | endif |
| 38 | 37 | ||
| 39 | DC_LIBS += dce120 | 38 | DC_LIBS += dce120 |
| @@ -1230,12 +1230,8 @@ static enum bp_result bios_parser_get_firmware_info( · 1229 unmodified lines | |||
| 1230 | result = get_firmware_info_v3_1(bp, info); | 1230 | result = get_firmware_info_v3_1(bp, info); |
| 1231 | break; | 1231 | break; |
| 1232 | case 2: | 1232 | case 2: |
| 1233 | result = get_firmware_info_v3_2(bp, info); | ||
| 1234 | break; | ||
| 1235 | case 3: | 1233 | case 3: |
| 1236 | #ifdef CONFIG_DRM_AMD_DC_DCN3_0 | ||
| 1237 | case 4: | 1234 | case 4: |
| 1238 | #endif | ||
| 1239 | result = get_firmware_info_v3_2(bp, info); | 1235 | result = get_firmware_info_v3_2(bp, info); |
| 1240 | break; | 1236 | break; |
| 1241 | default: | 1237 | default: |
| @@ -1743,6 +1739,165 @@ static enum bp_result get_integrated_info_v11( · 501 unmodified lines | |||
| 1743 | return BP_RESULT_OK; | 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 | * construct_integrated_info | 1903 | * construct_integrated_info |
| @@ -1775,11 +1930,25 @@ static enum bp_result construct_integrated_info( · 26 unmodified lines | |||
| 1775 | 1930 | ||
| 1776 | get_atom_data_table_revision(header, &revision); | 1931 | get_atom_data_table_revision(header, &revision); |
| 1777 | 1932 | ||
| 1778 | /* Don't need to check major revision as they are all 1 */ | 1933 | switch (revision.major) { |
| 1779 | switch (revision.minor) { | 1934 | case 1: |
| 1780 | case 11: | 1935 | switch (revision.minor) { |
| 1781 | case 12: | 1936 | case 11: |
| 1782 | result = get_integrated_info_v11(bp, info); | 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 | break; | 1952 | break; |
| 1784 | default: | 1953 | default: |
| 1785 | return result; | 1954 | return result; |
| @@ -70,15 +70,12 @@ bool dal_bios_parser_init_cmd_tbl_helper2( · 69 unmodified lines | |||
| 70 | case DCN_VERSION_1_01: | 70 | case DCN_VERSION_1_01: |
| 71 | case DCN_VERSION_2_0: | 71 | case DCN_VERSION_2_0: |
| 72 | case DCN_VERSION_2_1: | 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 | case DCN_VERSION_3_0: | 73 | case DCN_VERSION_3_0: |
| 74 | case DCN_VERSION_3_01: | ||
| 75 | case DCN_VERSION_3_02: | ||
| 78 | *h = dal_cmd_tbl_helper_dce112_get_table2(); | 76 | *h = dal_cmd_tbl_helper_dce112_get_table2(); |
| 79 | return true; | 77 | return true; |
| 80 | #endif | 78 | #endif |
| 81 | |||
| 82 | default: | 79 | default: |
| 83 | /* Unsupported DCE */ | 80 | /* Unsupported DCE */ |
| 84 | BREAK_TO_DEBUGGER(); | 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 | return &command_table_helper_funcs; | 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 | /* Initialize command table helper functions */ | 31 | /* Initialize command table helper functions */ |
| 32 | const struct command_table_helper *dal_cmd_tbl_helper_dce112_get_table2(void); | 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 | #endif /* __DAL_COMMAND_TABLE_HELPER_DCE110_H__ */ | 34 | #endif /* __DAL_COMMAND_TABLE_HELPER_DCE110_H__ */ |
| @@ -1364,13 +1364,10 @@ static void calculate_bandwidth( · 1363 unmodified lines | |||
| 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*/ | 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 | for (i = 0; i <= maximum_number_of_surfaces - 1; i++) { | 1365 | for (i = 0; i <= maximum_number_of_surfaces - 1; i++) { |
| 1366 | if (data->enable[i]) { | 1366 | if (data->enable[i]) { |
| 1367 | if (dceip->graphics_lb_nodownscaling_multi_line_prefetching == 1) { | 1367 | /*maximum_latency_hiding(i) = minimum_latency_hiding(i) + 1 / vsr(i) **/ |
| 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)); | 1368 | /* h_total(i) / pixel_rate(i) + 0.5 * total_dmifmc_urgent_latency*/ |
| 1369 | } | 1369 | data->maximum_latency_hiding[i] = bw_add(data->minimum_latency_hiding[i], |
| 1370 | else { | 1370 | bw_mul(bw_frc_to_fixed(5, 10), data->total_dmifmc_urgent_latency)); |
| 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 | } | ||
| 1374 | data->maximum_latency_hiding_with_cursor[i] = bw_min2(data->maximum_latency_hiding[i], data->cursor_latency_hiding[i]); | 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 | else { | 1977 | else { |
| 1981 | data->latency_for_non_mcifwr_clients = bw_int_to_fixed(0); | 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 | 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); | 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 | /*dram speed/p-state change margin*/ | 1982 | /*dram speed/p-state change margin*/ |
| 1986 | /*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*/ | 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 | input->src.viewport_width_c = input->src.viewport_width; | 381 | input->src.viewport_width_c = input->src.viewport_width; |
| 382 | input->src.viewport_height_c = input->src.viewport_height; | 382 | input->src.viewport_height_c = input->src.viewport_height; |
| 383 | break; | 383 | break; |
| 384 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 385 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA: | 384 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA: |
| 386 | input->src.source_format = dm_rgbe_alpha; | 385 | input->src.source_format = dm_rgbe_alpha; |
| 387 | input->src.viewport_width_c = input->src.viewport_width; | 386 | input->src.viewport_width_c = input->src.viewport_width; |
| 388 | input->src.viewport_height_c = input->src.viewport_height; | 387 | input->src.viewport_height_c = input->src.viewport_height; |
| 389 | break; | 388 | break; |
| 390 | #endif | ||
| 391 | default: | 389 | default: |
| 392 | input->src.source_format = dm_444_32; | 390 | input->src.source_format = dm_444_32; |
| 393 | input->src.viewport_width_c = input->src.viewport_width; | 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 | hack_force_pipe_split(v, context->streams[0]->timing.pix_clk_100hz); | 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 | /* for low power RV2 variants, the highest voltage level we want is 0 */ | 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 | switch (pci_revision_id) { | 742 | switch (pci_revision_id) { |
| 744 | case PRID_DALI_DE: | 743 | case PRID_DALI_DE: |
| 745 | case PRID_DALI_DF: | 744 | case PRID_DALI_DF: |
| @@ -1324,6 +1323,7 @@ bool dcn_validate_bandwidth( · 578 unmodified lines | |||
| 1324 | BW_VAL_TRACE_FINISH(); | 1323 | BW_VAL_TRACE_FINISH(); |
| 1325 | 1324 | ||
| 1326 | if (bw_limit_pass && v->voltage_level <= get_highest_allowed_voltage_level( | 1325 | if (bw_limit_pass && v->voltage_level <= get_highest_allowed_voltage_level( |
| 1326 | dc->ctx->asic_id.chip_family, | ||
| 1327 | dc->ctx->asic_id.hw_internal_rev, | 1327 | dc->ctx->asic_id.hw_internal_rev, |
| 1328 | dc->ctx->asic_id.pci_revision_id)) | 1328 | dc->ctx->asic_id.pci_revision_id)) |
| 1329 | return true; | 1329 | return true; |
| @@ -114,14 +114,46 @@ endif · 113 unmodified lines | |||
| 114 | AMD_DAL_CLK_MGR_DCN21 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn21/,$(CLK_MGR_DCN21)) | 114 | AMD_DAL_CLK_MGR_DCN21 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn21/,$(CLK_MGR_DCN21)) |
| 115 | 115 | ||
| 116 | AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN21) | 116 | AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN21) |
| 117 | endif | ||
| 118 | ifdef CONFIG_DRM_AMD_DC_DCN3_0 | ||
| 119 | ############################################################################### | 117 | ############################################################################### |
| 120 | # DCN30 | 118 | # DCN30 |
| 121 | ############################################################################### | 119 | ############################################################################### |
| 122 | CLK_MGR_DCN30 = dcn30_clk_mgr.o dcn30_clk_mgr_smu_msg.o | 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 | AMD_DAL_CLK_MGR_DCN30 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn30/,$(CLK_MGR_DCN30)) | 135 | AMD_DAL_CLK_MGR_DCN30 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn30/,$(CLK_MGR_DCN30)) |
| 125 | 136 | ||
| 126 | AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN30) | 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 | endif | 159 | endif |
| @@ -39,9 +39,8 @@ · 38 unmodified lines | |||
| 39 | #include "dcn10/rv2_clk_mgr.h" | 39 | #include "dcn10/rv2_clk_mgr.h" |
| 40 | #include "dcn20/dcn20_clk_mgr.h" | 40 | #include "dcn20/dcn20_clk_mgr.h" |
| 41 | #include "dcn21/rn_clk_mgr.h" | 41 | #include "dcn21/rn_clk_mgr.h" |
| 42 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 43 | #include "dcn30/dcn30_clk_mgr.h" | 42 | #include "dcn30/dcn30_clk_mgr.h" |
| 44 | #endif | 43 | #include "dcn301/vg_clk_mgr.h" |
| 45 | 44 | ||
| 46 | 45 | ||
| 47 | int clk_mgr_helper_get_active_display_cnt( | 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 | rn_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); | 165 | rn_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); |
| 167 | break; | 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 | if (ASICREV_IS_RAVEN2(asic_id.hw_internal_rev)) { | 173 | if (ASICREV_IS_RAVEN2(asic_id.hw_internal_rev)) { |
| 170 | rv2_clk_mgr_construct(ctx, clk_mgr, pp_smu); | 174 | rv2_clk_mgr_construct(ctx, clk_mgr, pp_smu); |
| 171 | break; | 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 | break; | 182 | break; |
| 179 | 183 | ||
| 180 | case FAMILY_NV: | 184 | case FAMILY_NV: |
| 181 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 182 | if (ASICREV_IS_SIENNA_CICHLID_P(asic_id.hw_internal_rev)) { | 185 | if (ASICREV_IS_SIENNA_CICHLID_P(asic_id.hw_internal_rev)) { |
| 183 | dcn3_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); | 186 | dcn3_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); |
| 184 | break; | 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 | dcn20_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); | 193 | dcn20_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); |
| 188 | break; | 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 | default: | 201 | default: |
| 192 | ASSERT(0); /* Unknown Asic */ | 202 | ASSERT(0); /* Unknown Asic */ |
| 193 | break; | 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 | void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base) | 209 | void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base) |
| 200 | { | 210 | { |
| 201 | struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); | 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 | switch (clk_mgr_base->ctx->asic_id.chip_family) { | 214 | switch (clk_mgr_base->ctx->asic_id.chip_family) { |
| 205 | case FAMILY_NV: | 215 | case FAMILY_NV: |
| 206 | if (ASICREV_IS_SIENNA_CICHLID_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) { | 216 | if (ASICREV_IS_SIENNA_CICHLID_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) { |
| 207 | dcn3_clk_mgr_destroy(clk_mgr); | 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 | #endif | 229 | #endif |
| 212 | 230 | ||
| @@ -195,7 +195,8 @@ void dce11_pplib_apply_display_requirements( · 194 unmodified lines | |||
| 195 | * , then change minimum memory clock based on real-time bandwidth | 195 | * , then change minimum memory clock based on real-time bandwidth |
| 196 | * limitation. | 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 | pp_display_cfg->min_memory_clock_khz = max(pp_display_cfg->min_memory_clock_khz, | 200 | pp_display_cfg->min_memory_clock_khz = max(pp_display_cfg->min_memory_clock_khz, |
| 200 | (uint32_t) div64_s64( | 201 | (uint32_t) div64_s64( |
| 201 | div64_s64(dc->bw_vbios->high_yclk.value, | 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 | /*VBIOS will determine DPREFCLK frequency, so we don't set it*/ | 100 | /*VBIOS will determine DPREFCLK frequency, so we don't set it*/ |
| 101 | dce_clk_params.target_clock_frequency = 0; | 101 | dce_clk_params.target_clock_frequency = 0; |
| 102 | dce_clk_params.clock_type = DCECLOCK_TYPE_DPREFCLK; | 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 | dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = | 106 | dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = |
| 105 | (dce_clk_params.pll_id == | 107 | (dce_clk_params.pll_id == |
| 106 | CLOCK_SOURCE_COMBO_DISPLAY_PLL0); | 108 | CLOCK_SOURCE_COMBO_DISPLAY_PLL0); |
| @@ -176,7 +178,8 @@ int dce112_set_dprefclk(struct clk_mgr_internal *clk_mgr) · 69 unmodified lines | |||
| 176 | dce_clk_params.target_clock_frequency = 0; | 178 | dce_clk_params.target_clock_frequency = 0; |
| 177 | dce_clk_params.pll_id = CLOCK_SOURCE_ID_DFS; | 179 | dce_clk_params.pll_id = CLOCK_SOURCE_ID_DFS; |
| 178 | dce_clk_params.clock_type = DCECLOCK_TYPE_DPREFCLK; | 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 | dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = | 183 | dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = |
| 181 | (dce_clk_params.pll_id == | 184 | (dce_clk_params.pll_id == |
| 182 | CLOCK_SOURCE_COMBO_DISPLAY_PLL0); | 185 | CLOCK_SOURCE_COMBO_DISPLAY_PLL0); |
| @@ -187,6 +187,17 @@ static void ramp_up_dispclk_with_dpp( · 186 unmodified lines | |||
| 187 | clk_mgr->base.clks.max_supported_dppclk_khz = new_clocks->max_supported_dppclk_khz; | 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 | static void rv1_update_clocks(struct clk_mgr *clk_mgr_base, | 201 | static void rv1_update_clocks(struct clk_mgr *clk_mgr_base, |
| 191 | struct dc_state *context, | 202 | struct dc_state *context, |
| 192 | bool safe_to_lower) | 203 | bool safe_to_lower) |
| @@ -284,9 +295,22 @@ static void rv1_update_clocks(struct clk_mgr *clk_mgr_base, · 91 unmodified lines | |||
| 284 | if (pp_smu->set_hard_min_fclk_by_freq && | 295 | if (pp_smu->set_hard_min_fclk_by_freq && |
| 285 | pp_smu->set_hard_min_dcfclk_by_freq && | 296 | pp_smu->set_hard_min_dcfclk_by_freq && |
| 286 | pp_smu->set_min_deep_sleep_dcfclk) { | 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); | 298 | // Only increase clocks when display is active and MPO is enabled |
| 288 | pp_smu->set_hard_min_dcfclk_by_freq(&pp_smu->pp_smu, new_clocks->dcfclk_khz / 1000); | 299 | if (display_count && is_mpo_enabled(context)) { |
| 289 | pp_smu->set_min_deep_sleep_dcfclk(&pp_smu->pp_smu, (new_clocks->dcfclk_deep_sleep_khz + 999) / 1000); | 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 | * if it is safe to lower, but we are already in the lower state, we don't have to do anything | 124 | * if it is safe to lower, but we are already in the lower state, we don't have to do anything |
| 125 | * also if safe to lower is false, we just go in the higher state | 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 | /* check that we're not already in lower */ | 128 | /* check that we're not already in lower */ |
| 129 | if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) { | 129 | if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) { |
| 130 | 130 | ||
| @@ -53,6 +53,7 @@ · 52 unmodified lines | |||
| 53 | #define DALSMC_MSG_GetDcModeMaxDpmFreq 0xC | 53 | #define DALSMC_MSG_GetDcModeMaxDpmFreq 0xC |
| 54 | #define DALSMC_MSG_SetMinDeepSleepDcefclk 0xD | 54 | #define DALSMC_MSG_SetMinDeepSleepDcefclk 0xD |
| 55 | #define DALSMC_MSG_NumOfDisplays 0xE | 55 | #define DALSMC_MSG_NumOfDisplays 0xE |
| 56 | #define DALSMC_MSG_SetDisplayRefreshFromMall 0xF | ||
| 56 | #define DALSMC_MSG_SetExternalClientDfCstateAllow 0x10 | 57 | #define DALSMC_MSG_SetExternalClientDfCstateAllow 0x10 |
| 57 | #define DALSMC_MSG_BacoAudioD3PME 0x11 | 58 | #define DALSMC_MSG_BacoAudioD3PME 0x11 |
| 58 | #define DALSMC_Message_Count 0x12 | 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 | /* defaults */ | 109 | /* defaults */ |
| 110 | double pstate_latency_us = clk_mgr->base.ctx->dc->dml.soc.dram_clock_change_latency_us; | 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 | clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz; | 145 | clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz; |
| 146 | clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF; | 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 | void dcn3_init_clocks(struct clk_mgr *clk_mgr_base) | 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 | clk_mgr_base->funcs->get_memclk_states_from_smu(clk_mgr_base); | 211 | clk_mgr_base->funcs->get_memclk_states_from_smu(clk_mgr_base); |
| 202 | 212 | ||
| 203 | /* WM range table */ | 213 | /* WM range table */ |
| 214 | DC_FP_START(); | ||
| 204 | dcn3_build_wm_range_table(clk_mgr); | 215 | dcn3_build_wm_range_table(clk_mgr); |
| 216 | DC_FP_END(); | ||
| 205 | } | 217 | } |
| 206 | 218 | ||
| 207 | static int dcn30_get_vco_frequency_from_reg(struct clk_mgr_internal *clk_mgr) | 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 | DALSMC_MSG_NumOfDisplays, num_displays, NULL); | 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 | void dcn30_smu_set_external_client_df_cstate_allow(struct clk_mgr_internal *clk_mgr, bool enable) | 309 | void dcn30_smu_set_external_client_df_cstate_allow(struct clk_mgr_internal *clk_mgr, bool enable) |
| 301 | { | 310 | { |
| 302 | smu_print("SMU Set external client df cstate allow: enable = %d\n", enable); | 311 | smu_print("SMU Set external client df cstate allow: enable = %d\n", enable); |
| @@ -70,6 +70,7 @@ typedef enum { · 69 unmodified lines | |||
| 70 | typedef enum { | 70 | typedef enum { |
| 71 | WATERMARKS_CLOCK_RANGE = 0, | 71 | WATERMARKS_CLOCK_RANGE = 0, |
| 72 | WATERMARKS_DUMMY_PSTATE, | 72 | WATERMARKS_DUMMY_PSTATE, |
| 73 | WATERMARKS_MALL, | ||
| 73 | WATERMARKS_COUNT, | 74 | WATERMARKS_COUNT, |
| 74 | } WATERMARKS_FLAGS_e; | 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 | unsigned int dcn30_smu_get_dc_mode_max_dpm_freq(struct clk_mgr_internal *clk_mgr, PPCLK_e clk); | 103 | unsigned int dcn30_smu_get_dc_mode_max_dpm_freq(struct clk_mgr_internal *clk_mgr, PPCLK_e clk); |
| 103 | void dcn30_smu_set_min_deep_sleep_dcef_clk(struct clk_mgr_internal *clk_mgr, uint32_t freq_mhz); | 104 | void dcn30_smu_set_min_deep_sleep_dcef_clk(struct clk_mgr_internal *clk_mgr, uint32_t freq_mhz); |
| 104 | void dcn30_smu_set_num_of_displays(struct clk_mgr_internal *clk_mgr, uint32_t num_displays); | 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 | void dcn30_smu_set_external_client_df_cstate_allow(struct clk_mgr_internal *clk_mgr, bool enable); | 107 | void dcn30_smu_set_external_client_df_cstate_allow(struct clk_mgr_internal *clk_mgr, bool enable); |
| 106 | void dcn30_smu_set_pme_workaround(struct clk_mgr_internal *clk_mgr); | 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 | #include "dce/dmub_hw_lock_mgr.h" | 71 | #include "dce/dmub_hw_lock_mgr.h" |
| 72 | 72 | ||
| 73 | #include "dc_trace.h" | ||
| 74 | |||
| 73 | #define CTX \ | 75 | #define CTX \ |
| 74 | dc->ctx | 76 | dc->ctx |
| 75 | 77 | ||
| @@ -344,7 +346,7 @@ bool dc_stream_get_crtc_position(struct dc *dc, · 268 unmodified lines | |||
| 344 | * calculate the crc. | 346 | * calculate the crc. |
| 345 | */ | 347 | */ |
| 346 | bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream, | 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 | int i; | 351 | int i; |
| 350 | struct pipe_ctx *pipe; | 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 | if (i == MAX_PIPES) | 362 | if (i == MAX_PIPES) |
| 361 | return false; | 363 | return false; |
| 362 | 364 | ||
| 363 | /* Always capture the full frame */ | 365 | /* By default, capture the full frame */ |
| 364 | param.windowa_x_start = 0; | 366 | param.windowa_x_start = 0; |
| 365 | param.windowa_y_start = 0; | 367 | param.windowa_y_start = 0; |
| 366 | param.windowa_x_end = pipe->stream->timing.h_addressable; | 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 | param.windowb_x_end = pipe->stream->timing.h_addressable; | 372 | param.windowb_x_end = pipe->stream->timing.h_addressable; |
| 371 | param.windowb_y_end = pipe->stream->timing.v_addressable; | 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 | param.dsc_mode = pipe->stream->timing.flags.DSC ? 1:0; | 386 | param.dsc_mode = pipe->stream->timing.flags.DSC ? 1:0; |
| 374 | param.odm_mode = pipe->next_odm_pipe ? 1:0; | 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 | dc->clk_mgr = dc_clk_mgr_create(dc->ctx, dc->res_pool->pp_smu, dc->res_pool->dccg); | 744 | dc->clk_mgr = dc_clk_mgr_create(dc->ctx, dc->res_pool->pp_smu, dc->res_pool->dccg); |
| 732 | if (!dc->clk_mgr) | 745 | if (!dc->clk_mgr) |
| 733 | goto fail; | 746 | goto fail; |
| 734 | #ifdef CONFIG_DRM_AMD_DC_DCN3_0 | 747 | #ifdef CONFIG_DRM_AMD_DC_DCN |
| 735 | dc->clk_mgr->force_smu_not_present = init_params->force_smu_not_present; | 748 | dc->clk_mgr->force_smu_not_present = init_params->force_smu_not_present; |
| 736 | #endif | 749 | #endif |
| 737 | 750 | ||
| @@ -763,7 +776,7 @@ fail: · 25 unmodified lines | |||
| 763 | return false; | 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 | const struct dc *dc, | 780 | const struct dc *dc, |
| 768 | struct dc_stream_state *stream, | 781 | struct dc_stream_state *stream, |
| 769 | struct dc_state *context) | 782 | struct dc_state *context) |
| @@ -772,8 +785,6 @@ static bool disable_all_writeback_pipes_for_stream( · 2 unmodified lines | |||
| 772 | 785 | ||
| 773 | for (i = 0; i < stream->num_wb_info; i++) | 786 | for (i = 0; i < stream->num_wb_info; i++) |
| 774 | stream->writeback_info[i].wb_enabled = false; | 787 | stream->writeback_info[i].wb_enabled = false; |
| 775 | |||
| 776 | return true; | ||
| 777 | } | 788 | } |
| 778 | 789 | ||
| 779 | void apply_ctx_interdependent_lock(struct dc *dc, struct dc_state *context, struct dc_stream_state *stream, bool lock) | 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 | if (stream == NULL) | 872 | if (stream == NULL) |
| 862 | continue; | 873 | continue; |
| 863 | 874 | ||
| 875 | // only looking for first odm pipe | ||
| 876 | if (pipe->prev_odm_pipe) | ||
| 877 | continue; | ||
| 878 | |||
| 864 | if (stream->link->local_sink && | 879 | if (stream->link->local_sink && |
| 865 | stream->link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { | 880 | stream->link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { |
| 866 | link = stream->link; | 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 | unsigned int enc_inst, tg_inst = 0; | 885 | unsigned int enc_inst, tg_inst = 0; |
| 871 | unsigned int pix_clk_100hz; | 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 | return false; | 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 | return true; | 1288 | return true; |
| 1270 | } | 1289 | } |
| 1271 | 1290 | ||
| 1272 | bool dc_enable_stereo( | 1291 | void dc_enable_stereo( |
| 1273 | struct dc *dc, | 1292 | struct dc *dc, |
| 1274 | struct dc_state *context, | 1293 | struct dc_state *context, |
| 1275 | struct dc_stream_state *streams[], | 1294 | struct dc_stream_state *streams[], |
| 1276 | uint8_t stream_count) | 1295 | uint8_t stream_count) |
| 1277 | { | 1296 | { |
| 1278 | bool ret = true; | ||
| 1279 | int i, j; | 1297 | int i, j; |
| 1280 | struct pipe_ctx *pipe; | 1298 | struct pipe_ctx *pipe; |
| 1281 | 1299 | ||
| @@ -1290,8 +1308,6 @@ bool dc_enable_stereo( · 8 unmodified lines | |||
| 1290 | dc->hwss.setup_stereo(pipe, dc); | 1308 | dc->hwss.setup_stereo(pipe, dc); |
| 1291 | } | 1309 | } |
| 1292 | } | 1310 | } |
| 1293 | |||
| 1294 | return ret; | ||
| 1295 | } | 1311 | } |
| 1296 | 1312 | ||
| 1297 | void dc_trigger_sync(struct dc *dc, struct dc_state *context) | 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 | int i, k, l; | 1343 | int i, k, l; |
| 1328 | struct dc_stream_state *dc_streams[MAX_STREAMS] = {0}; | 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 | dc_allow_idle_optimizations(dc, false); | 1347 | dc_allow_idle_optimizations(dc, false); |
| 1332 | #endif | 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 | dc->hwss.optimize_bandwidth(dc, context); | 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 | context->stream_mask = get_stream_mask(dc, context); | 1458 | context->stream_mask = get_stream_mask(dc, context); |
| 1438 | 1459 | ||
| 1439 | if (context->stream_mask != dc->current_state->stream_mask) | 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 | return (result == DC_OK); | 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 | bool dc_acquire_release_mpc_3dlut( | 1498 | bool dc_acquire_release_mpc_3dlut( |
| 1478 | struct dc *dc, bool acquire, | 1499 | struct dc *dc, bool acquire, |
| 1479 | struct dc_stream_state *stream, | 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 | return false; | 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 | int i; | 1556 | int i; |
| 1536 | struct dc_state *context = dc->current_state; | 1557 | struct dc_state *context = dc->current_state; |
| 1537 | 1558 | ||
| 1538 | if ((!dc->optimized_required) || dc->optimize_seamless_boot_streams > 0) | 1559 | if ((!dc->optimized_required) || dc->optimize_seamless_boot_streams > 0) |
| 1539 | return true; | 1560 | return; |
| 1540 | 1561 | ||
| 1541 | post_surface_trace(dc); | 1562 | post_surface_trace(dc); |
| 1542 | 1563 | ||
| 1543 | if (is_flip_pending_in_pipes(dc, context)) | 1564 | if (is_flip_pending_in_pipes(dc, context)) |
| 1544 | return true; | 1565 | return; |
| 1545 | 1566 | ||
| 1546 | for (i = 0; i < dc->res_pool->pipe_count; i++) | 1567 | for (i = 0; i < dc->res_pool->pipe_count; i++) |
| 1547 | if (context->res_ctx.pipe_ctx[i].stream == NULL || | 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 | dc->optimized_required = false; | 1576 | dc->optimized_required = false; |
| 1556 | dc->wm_optimized_required = false; | 1577 | dc->wm_optimized_required = false; |
| 1557 | |||
| 1558 | return true; | ||
| 1559 | } | 1578 | } |
| 1560 | 1579 | ||
| 1561 | static void init_state(struct dc *dc, struct dc_state *context) | 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 | int i; | 1948 | int i; |
| 1930 | enum surface_update_type overall_type = UPDATE_TYPE_FAST; | 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 | if (dc->idle_optimizations_allowed) | 1952 | if (dc->idle_optimizations_allowed) |
| 1934 | overall_type = UPDATE_TYPE_FULL; | 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 | enum surface_update_type update_type, | 2402 | enum surface_update_type update_type, |
| 2384 | struct dc_state *context) | 2403 | struct dc_state *context) |
| 2385 | { | 2404 | { |
| 2386 | bool mpcc_disconnected = false; | ||
| 2387 | int i, j; | 2405 | int i, j; |
| 2388 | struct pipe_ctx *top_pipe_to_program = NULL; | 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 | if (update_type == UPDATE_TYPE_FULL) { | 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 | dc_allow_idle_optimizations(dc, false); | 2426 | dc_allow_idle_optimizations(dc, false); |
| 2409 | 2427 | ||
| 2410 | #endif | 2428 | #endif |
| @@ -2414,15 +2432,6 @@ static void commit_planes_for_stream(struct dc *dc, · 3 unmodified lines | |||
| 2414 | context_clock_trace(dc, context); | 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 | for (j = 0; j < dc->res_pool->pipe_count; j++) { | 2435 | for (j = 0; j < dc->res_pool->pipe_count; j++) { |
| 2427 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; | 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 | dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true); | 2471 | dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true); |
| 2463 | 2472 | ||
| 2464 | |||
| 2465 | // Stream updates | 2473 | // Stream updates |
| 2466 | if (stream_update) | 2474 | if (stream_update) |
| 2467 | commit_planes_do_stream_update(dc, stream, stream_update, update_type, context); | 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 | for (j = 0; j < dc->res_pool->pipe_count; j++) { | 2649 | for (j = 0; j < dc->res_pool->pipe_count; j++) { |
| 2642 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; | 2650 | struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; |
| 2643 | 2651 | ||
| 2644 | if (pipe_ctx->bottom_pipe || | 2652 | if (pipe_ctx->bottom_pipe || pipe_ctx->next_odm_pipe || |
| 2645 | !pipe_ctx->stream || | 2653 | !pipe_ctx->stream || pipe_ctx->stream != stream || |
| 2646 | pipe_ctx->stream != stream || | ||
| 2647 | !pipe_ctx->plane_state->update_flags.bits.addr_update) | 2654 | !pipe_ctx->plane_state->update_flags.bits.addr_update) |
| 2648 | continue; | 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 | commit_planes_for_stream( | 2736 | commit_planes_for_stream( |
| 2728 | dc, | 2737 | dc, |
| 2729 | srf_updates, | 2738 | srf_updates, |
| @@ -2748,9 +2757,15 @@ void dc_commit_updates_for_stream(struct dc *dc, · 18 unmodified lines | |||
| 2748 | } | 2757 | } |
| 2749 | } | 2758 | } |
| 2750 | /*let's use current_state to update watermark etc*/ | 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 | dc_post_update_surfaces_to_stream(dc); | 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 | return; | 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 | return true; | 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 | void dc_allow_idle_optimizations(struct dc *dc, bool allow) | 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 | return false; | 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 | #endif | 3129 | #endif |
| @@ -418,6 +418,10 @@ char *dc_status_to_str(enum dc_status status) · 417 unmodified lines | |||
| 418 | return "Fail clk below minimum"; | 418 | return "Fail clk below minimum"; |
| 419 | case DC_FAIL_CLK_BELOW_CFG_REQUIRED: | 419 | case DC_FAIL_CLK_BELOW_CFG_REQUIRED: |
| 420 | return "Fail clk below required CFG (hard_min in PPLIB)"; | 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 | case DC_ERROR_UNEXPECTED: | 425 | case DC_ERROR_UNEXPECTED: |
| 422 | return "Unexpected error"; | 426 | return "Unexpected error"; |
| 423 | } | 427 | } |
| @@ -854,6 +854,7 @@ static bool dc_link_detect_helper(struct dc_link *link, · 853 unmodified lines | |||
| 854 | struct dpcd_caps prev_dpcd_caps; | 854 | struct dpcd_caps prev_dpcd_caps; |
| 855 | bool same_dpcd = true; | 855 | bool same_dpcd = true; |
| 856 | enum dc_connection_type new_connection_type = dc_connection_none; | 856 | enum dc_connection_type new_connection_type = dc_connection_none; |
| 857 | enum dc_connection_type pre_connection_type = dc_connection_none; | ||
| 857 | bool perform_dp_seamless_boot = false; | 858 | bool perform_dp_seamless_boot = false; |
| 858 | const uint32_t post_oui_delay = 30; // 30ms | 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 | link_disconnect_sink(link); | 891 | link_disconnect_sink(link); |
| 891 | if (new_connection_type != dc_connection_none) { | 892 | if (new_connection_type != dc_connection_none) { |
| 893 | pre_connection_type = link->type; | ||
| 892 | link->type = new_connection_type; | 894 | link->type = new_connection_type; |
| 893 | link->link_state_valid = false; | 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 | return true; | 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 | if (link->type == dc_connection_mst_branch) { | 973 | if (link->type == dc_connection_mst_branch) { |
| 966 | LINK_INFO("link=%d, mst branch is now Connected\n", | 974 | LINK_INFO("link=%d, mst branch is now Connected\n", |
| 967 | link->link_index); | 975 | link->link_index); |
| @@ -2732,7 +2740,8 @@ bool dc_link_setup_psr(struct dc_link *link, · 1764 unmodified lines | |||
| 2732 | 2740 | ||
| 2733 | #if defined(CONFIG_DRM_AMD_DC_DCN) | 2741 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| 2734 | /*skip power down the single pipe since it blocks the cstate*/ | 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 | psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true; | 2745 | psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true; |
| 2737 | #endif | 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 | /* slot X.Y for only current stream */ | 2953 | /* slot X.Y for only current stream */ |
| 2945 | pbn_per_slot = get_pbn_per_slot(stream); | 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 | pbn = get_pbn_from_timing(pipe_ctx); | 2959 | pbn = get_pbn_from_timing(pipe_ctx); |
| 2947 | avg_time_slots_per_mtp = dc_fixpt_div(pbn, pbn_per_slot); | 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 | struct dc *dc = pipe_ctx->stream->ctx->dc; | 3119 | struct dc *dc = pipe_ctx->stream->ctx->dc; |
| 3107 | struct dc_stream_state *stream = pipe_ctx->stream; | 3120 | struct dc_stream_state *stream = pipe_ctx->stream; |
| 3108 | enum dc_status status; | 3121 | enum dc_status status; |
| 3109 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | 3122 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| 3110 | enum otg_out_mux_dest otg_out_dest = OUT_MUX_DIO; | 3123 | enum otg_out_mux_dest otg_out_dest = OUT_MUX_DIO; |
| 3111 | #endif | 3124 | #endif |
| 3112 | DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger); | 3125 | DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger); |
| @@ -3142,7 +3155,7 @@ void core_link_enable_stream( · 29 unmodified lines | |||
| 3142 | 3155 | ||
| 3143 | pipe_ctx->stream->link->link_state_valid = true; | 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 | if (pipe_ctx->stream_res.tg->funcs->set_out_mux) | 3159 | if (pipe_ctx->stream_res.tg->funcs->set_out_mux) |
| 3147 | pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, otg_out_dest); | 3160 | pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, otg_out_dest); |
| 3148 | #endif | 3161 | #endif |
| @@ -3283,8 +3296,9 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx) · 134 unmodified lines | |||
| 3283 | dc_is_virtual_signal(pipe_ctx->stream->signal)) | 3296 | dc_is_virtual_signal(pipe_ctx->stream->signal)) |
| 3284 | return; | 3297 | return; |
| 3285 | 3298 | ||
| 3286 | if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) { | 3299 | if (!pipe_ctx->stream->sink->edid_caps.panel_patch.skip_avmute) { |
| 3287 | core_link_set_avmute(pipe_ctx, true); | 3300 | if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) |
| 3301 | core_link_set_avmute(pipe_ctx, true); | ||
| 3288 | } | 3302 | } |
| 3289 | 3303 | ||
| 3290 | #if defined(CONFIG_DRM_AMD_DC_HDCP) | 3304 | #if defined(CONFIG_DRM_AMD_DC_HDCP) |
| @@ -39,6 +39,7 @@ · 38 unmodified lines | |||
| 39 | 39 | ||
| 40 | #define AUX_POWER_UP_WA_DELAY 500 | 40 | #define AUX_POWER_UP_WA_DELAY 500 |
| 41 | #define I2C_OVER_AUX_DEFER_WA_DELAY 70 | 41 | #define I2C_OVER_AUX_DEFER_WA_DELAY 70 |
| 42 | #define I2C_OVER_AUX_DEFER_WA_DELAY_1MS 1 | ||
| 42 | 43 | ||
| 43 | /* CV smart dongle slave address for retrieving supported HDTV modes*/ | 44 | /* CV smart dongle slave address for retrieving supported HDTV modes*/ |
| 44 | #define CV_SMART_DONGLE_ADDRESS 0x20 | 45 | #define CV_SMART_DONGLE_ADDRESS 0x20 |
| @@ -282,11 +283,17 @@ static uint32_t defer_delay_converter_wa( · 237 unmodified lines | |||
| 282 | struct dc_link *link = ddc->link; | 283 | struct dc_link *link = ddc->link; |
| 283 | 284 | ||
| 284 | if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_0080E1 && | 285 | if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_0080E1 && |
| 285 | !memcmp(link->dpcd_caps.branch_dev_name, | 286 | !memcmp(link->dpcd_caps.branch_dev_name, |
| 286 | DP_DVI_CONVERTER_ID_4, | 287 | DP_DVI_CONVERTER_ID_4, |
| 287 | sizeof(link->dpcd_caps.branch_dev_name))) | 288 | sizeof(link->dpcd_caps.branch_dev_name))) |
| 288 | return defer_delay > I2C_OVER_AUX_DEFER_WA_DELAY ? | 289 | return defer_delay > I2C_OVER_AUX_DEFER_WA_DELAY ? |
| 289 | defer_delay : I2C_OVER_AUX_DEFER_WA_DELAY; | 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 | return defer_delay; | 298 | return defer_delay; |
| 292 | } | 299 | } |
| @@ -17,16 +17,16 @@ · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | #define DC_LOGGER \ | 18 | #define DC_LOGGER \ |
| 19 | link->ctx->logger | 19 | link->ctx->logger |
| 20 | 20 | #define DC_TRACE_LEVEL_MESSAGE(...) /* do nothing */ | |
| 21 | 21 | ||
| 22 | #define DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE 0x50 | 22 | #define DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE 0x50 |
| 23 | 23 | ||
| 24 | /* maximum pre emphasis level allowed for each voltage swing level*/ | 24 | /* maximum pre emphasis level allowed for each voltage swing level*/ |
| 25 | static const enum dc_pre_emphasis voltage_swing_to_pre_emphasis[] = { | 25 | static const enum dc_pre_emphasis |
| 26 | PRE_EMPHASIS_LEVEL3, | 26 | voltage_swing_to_pre_emphasis[] = { PRE_EMPHASIS_LEVEL3, |
| 27 | PRE_EMPHASIS_LEVEL2, | 27 | PRE_EMPHASIS_LEVEL2, |
| 28 | PRE_EMPHASIS_LEVEL1, | 28 | PRE_EMPHASIS_LEVEL1, |
| 29 | PRE_EMPHASIS_DISABLED }; | 29 | PRE_EMPHASIS_DISABLED }; |
| 30 | 30 | ||
| 31 | enum { | 31 | enum { |
| 32 | POST_LT_ADJ_REQ_LIMIT = 6, | 32 | POST_LT_ADJ_REQ_LIMIT = 6, |
| @@ -183,6 +183,16 @@ static void dpcd_set_link_settings( · 150 unmodified lines | |||
| 183 | if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 && | 183 | if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 && |
| 184 | lt_settings->link_settings.use_link_rate_set == true) { | 184 | lt_settings->link_settings.use_link_rate_set == true) { |
| 185 | rate = 0; | 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 | core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1); | 196 | core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1); |
| 187 | core_link_write_dpcd(link, DP_LINK_RATE_SET, | 197 | core_link_write_dpcd(link, DP_LINK_RATE_SET, |
| 188 | <_settings->link_settings.link_rate_set, 1); | 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 | if (pipe_ctx->stream_res.tg->funcs->set_test_pattern) | 3858 | if (pipe_ctx->stream_res.tg->funcs->set_test_pattern) |
| 3849 | pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, | 3859 | pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, |
| 3850 | controller_test_pattern, color_depth); | 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 | struct pipe_ctx *odm_pipe; | 3862 | struct pipe_ctx *odm_pipe; |
| 3853 | enum controller_dp_color_space controller_color_space; | 3863 | enum controller_dp_color_space controller_color_space; |
| 3854 | int opp_cnt = 1; | 3864 | int opp_cnt = 1; |
| @@ -3878,26 +3888,29 @@ static void set_crtc_test_pattern(struct dc_link *link, · 23 unmodified lines | |||
| 3878 | dpg_width = width / opp_cnt; | 3888 | dpg_width = width / opp_cnt; |
| 3879 | offset = dpg_width; | 3889 | offset = dpg_width; |
| 3880 | 3890 | ||
| 3881 | opp->funcs->opp_set_disp_pattern_generator(opp, | 3891 | link->dc->hwss.set_disp_pattern_generator(link->dc, |
| 3882 | controller_test_pattern, | 3892 | pipe_ctx, |
| 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, | ||
| 3894 | controller_test_pattern, | 3893 | controller_test_pattern, |
| 3895 | controller_color_space, | 3894 | controller_color_space, |
| 3896 | color_depth, | 3895 | color_depth, |
| 3897 | NULL, | 3896 | NULL, |
| 3898 | dpg_width, | 3897 | dpg_width, |
| 3899 | height, | 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 | offset += offset; | 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 | pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, | 3926 | pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg, |
| 3914 | CONTROLLER_DP_TEST_PATTERN_VIDEOMODE, | 3927 | CONTROLLER_DP_TEST_PATTERN_VIDEOMODE, |
| 3915 | color_depth); | 3928 | color_depth); |
| 3916 | else if (opp->funcs->opp_set_disp_pattern_generator) { | 3929 | else if (link->dc->hwss.set_disp_pattern_generator) { |
| 3917 | struct pipe_ctx *odm_pipe; | 3930 | struct pipe_ctx *odm_pipe; |
| 3918 | int opp_cnt = 1; | 3931 | int opp_cnt = 1; |
| 3919 | int dpg_width = width; | 3932 | int dpg_width = width; |
| @@ -3926,7 +3939,18 @@ static void set_crtc_test_pattern(struct dc_link *link, · 6 unmodified lines | |||
| 3926 | struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp; | 3939 | struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp; |
| 3927 | 3940 | ||
| 3928 | odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, ¶ms); | 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 | CONTROLLER_DP_TEST_PATTERN_VIDEOMODE, | 3954 | CONTROLLER_DP_TEST_PATTERN_VIDEOMODE, |
| 3931 | CONTROLLER_DP_COLOR_SPACE_UDEFINED, | 3955 | CONTROLLER_DP_COLOR_SPACE_UDEFINED, |
| 3932 | color_depth, | 3956 | color_depth, |
| @@ -3934,15 +3958,6 @@ static void set_crtc_test_pattern(struct dc_link *link, · 1 unmodified line | |||
| 3934 | dpg_width, | 3958 | dpg_width, |
| 3935 | height, | 3959 | height, |
| 3936 | 0); | 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 | break; | 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 | 3995 | /* Reset CRTC Test Pattern if it is currently running and request is VideoMode */ |
| 3981 | * is VideoMode Reset DP Phy Test Pattern if it is currently running | ||
| 3982 | * and request is VideoMode | ||
| 3983 | */ | ||
| 3984 | if (link->test_pattern_enabled && test_pattern == | 3996 | if (link->test_pattern_enabled && test_pattern == |
| 3985 | DP_TEST_PATTERN_VIDEO_MODE) { | 3997 | DP_TEST_PATTERN_VIDEO_MODE) { |
| 3986 | /* Set CRTC Test Pattern */ | 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 | if (edp_config_set.bits.PANEL_MODE_EDP | 4243 | if (edp_config_set.bits.PANEL_MODE_EDP |
| 4232 | != panel_mode_edp) { | 4244 | != panel_mode_edp) { |
| 4233 | enum ddc_result result = DDC_RESULT_UNKNOWN; | 4245 | enum dc_status result = DC_ERROR_UNEXPECTED; |
| 4234 | 4246 | ||
| 4235 | edp_config_set.bits.PANEL_MODE_EDP = | 4247 | edp_config_set.bits.PANEL_MODE_EDP = |
| 4236 | panel_mode_edp; | 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 | &edp_config_set.raw, | 4252 | &edp_config_set.raw, |
| 4241 | sizeof(edp_config_set.raw)); | 4253 | sizeof(edp_config_set.raw)); |
| 4242 | 4254 | ||
| 4243 | ASSERT(result == DDC_RESULT_SUCESSFULL); | 4255 | ASSERT(result == DC_OK); |
| 4244 | } | 4256 | } |
| 4245 | } | 4257 | } |
| 4246 | DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d " | 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 | void dpcd_set_source_specific_data(struct dc_link *link) | 4384 | void dpcd_set_source_specific_data(struct dc_link *link) |
| 4373 | { | 4385 | { |
| 4374 | if (!link->dc->vendor_signature.is_valid) { | 4386 | if (!link->dc->vendor_signature.is_valid) { |
| 4387 | enum dc_status result_write_min_hblank = DC_NOT_SUPPORTED; | ||
| 4375 | struct dpcd_amd_signature amd_signature; | 4388 | struct dpcd_amd_signature amd_signature; |
| 4376 | amd_signature.AMD_IEEE_TxSignature_byte1 = 0x0; | 4389 | amd_signature.AMD_IEEE_TxSignature_byte1 = 0x0; |
| 4377 | amd_signature.AMD_IEEE_TxSignature_byte2 = 0x0; | 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 | (uint8_t *)(&amd_signature), | 4403 | (uint8_t *)(&amd_signature), |
| 4391 | sizeof(amd_signature)); | 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 | } else { | 4430 | } else { |
| 4394 | core_link_write_dpcd(link, DP_SOURCE_OUI, | 4431 | core_link_write_dpcd(link, DP_SOURCE_OUI, |
| 4395 | link->dc->vendor_signature.data.raw, | 4432 | link->dc->vendor_signature.data.raw, |
| @@ -156,6 +156,13 @@ void dp_enable_link_phy( · 155 unmodified lines | |||
| 156 | dp_receiver_power_ctrl(link, true); | 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 | bool edp_receiver_ready_T9(struct dc_link *link) | 166 | bool edp_receiver_ready_T9(struct dc_link *link) |
| 160 | { | 167 | { |
| 161 | unsigned int tries = 0; | 168 | unsigned int tries = 0; |
| @@ -165,7 +172,7 @@ bool edp_receiver_ready_T9(struct dc_link *link) · 3 unmodified lines | |||
| 165 | 172 | ||
| 166 | result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev)); | 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 | if (result == DC_OK && edpRev >= DP_EDP_12) { | 176 | if (result == DC_OK && edpRev >= DP_EDP_12) { |
| 170 | do { | 177 | do { |
| 171 | sinkstatus = 1; | 178 | sinkstatus = 1; |
| @@ -178,10 +185,6 @@ bool edp_receiver_ready_T9(struct dc_link *link) · 6 unmodified lines | |||
| 178 | } while (++tries < 50); | 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 | return result; | 188 | return result; |
| 186 | } | 189 | } |
| 187 | bool edp_receiver_ready_T7(struct dc_link *link) | 190 | bool edp_receiver_ready_T7(struct dc_link *link) |
| @@ -54,9 +54,9 @@ · 53 unmodified lines | |||
| 54 | #include "dcn10/dcn10_resource.h" | 54 | #include "dcn10/dcn10_resource.h" |
| 55 | #include "dcn20/dcn20_resource.h" | 55 | #include "dcn20/dcn20_resource.h" |
| 56 | #include "dcn21/dcn21_resource.h" | 56 | #include "dcn21/dcn21_resource.h" |
| 57 | #endif | 57 | #include "dcn30/dcn30_resource.h" |
| 58 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | 58 | #include "dcn301/dcn301_resource.h" |
| 59 | #include "../dcn30/dcn30_resource.h" | 59 | #include "dcn302/dcn302_resource.h" |
| 60 | #endif | 60 | #endif |
| 61 | 61 | ||
| 62 | #define DC_LOGGER_INIT(logger) | 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 | dc_version = DCN_VERSION_1_01; | 120 | dc_version = DCN_VERSION_1_01; |
| 121 | if (ASICREV_IS_RENOIR(asic_id.hw_internal_rev)) | 121 | if (ASICREV_IS_RENOIR(asic_id.hw_internal_rev)) |
| 122 | dc_version = DCN_VERSION_2_1; | 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 | break; | 125 | break; |
| 124 | #endif | ||
| 125 | 126 | ||
| 126 | case FAMILY_NV: | 127 | case FAMILY_NV: |
| 127 | dc_version = DCN_VERSION_2_0; | 128 | dc_version = DCN_VERSION_2_0; |
| 128 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 129 | if (ASICREV_IS_SIENNA_CICHLID_P(asic_id.hw_internal_rev)) | 129 | if (ASICREV_IS_SIENNA_CICHLID_P(asic_id.hw_internal_rev)) |
| 130 | dc_version = DCN_VERSION_3_0; | 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 | break; | 133 | break; |
| 134 | |||
| 135 | case FAMILY_VGH: | ||
| 136 | dc_version = DCN_VERSION_3_01; | ||
| 137 | break; | ||
| 138 | #endif | ||
| 133 | default: | 139 | default: |
| 134 | dc_version = DCE_VERSION_UNKNOWN; | 140 | dc_version = DCE_VERSION_UNKNOWN; |
| 135 | break; | 141 | break; |
| @@ -195,21 +201,22 @@ struct resource_pool *dc_create_resource_pool(struct dc *dc, · 59 unmodified lines | |||
| 195 | case DCN_VERSION_1_01: | 201 | case DCN_VERSION_1_01: |
| 196 | res_pool = dcn10_create_resource_pool(init_data, dc); | 202 | res_pool = dcn10_create_resource_pool(init_data, dc); |
| 197 | break; | 203 | break; |
| 198 | |||
| 199 | |||
| 200 | case DCN_VERSION_2_0: | 204 | case DCN_VERSION_2_0: |
| 201 | res_pool = dcn20_create_resource_pool(init_data, dc); | 205 | res_pool = dcn20_create_resource_pool(init_data, dc); |
| 202 | break; | 206 | break; |
| 203 | case DCN_VERSION_2_1: | 207 | case DCN_VERSION_2_1: |
| 204 | res_pool = dcn21_create_resource_pool(init_data, dc); | 208 | res_pool = dcn21_create_resource_pool(init_data, dc); |
| 205 | break; | 209 | break; |
| 206 | #endif | ||
| 207 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 208 | case DCN_VERSION_3_0: | 210 | case DCN_VERSION_3_0: |
| 209 | res_pool = dcn30_create_resource_pool(init_data, dc); | 211 | res_pool = dcn30_create_resource_pool(init_data, dc); |
| 210 | break; | 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 | #endif | 219 | #endif |
| 212 | |||
| 213 | default: | 220 | default: |
| 214 | break; | 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 | for (i = 0; i < caps->num_mpc_3dlut; i++) { | 334 | for (i = 0; i < caps->num_mpc_3dlut; i++) { |
| 328 | pool->mpc_lut[i] = dc_create_3dlut_func(); | 335 | pool->mpc_lut[i] = dc_create_3dlut_func(); |
| 329 | if (pool->mpc_lut[i] == NULL) | 336 | if (pool->mpc_lut[i] == NULL) |
| @@ -794,6 +801,8 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx) · 464 unmodified lines | |||
| 794 | } else | 801 | } else |
| 795 | data->recout.x = 0; | 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 | data->recout.width = surf_clip.width * stream->dst.width / stream->src.width; | 806 | data->recout.width = surf_clip.width * stream->dst.width / stream->src.width; |
| 798 | if (data->recout.width + data->recout.x > stream->dst.x + stream->dst.width) | 807 | if (data->recout.width + data->recout.x > stream->dst.x + stream->dst.width) |
| 799 | data->recout.width = stream->dst.x + stream->dst.width - data->recout.x; | 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 | if (stream->src.y < surf_clip.y) | 811 | if (stream->src.y < surf_clip.y) |
| 803 | data->recout.y += (surf_clip.y - stream->src.y) * stream->dst.height | 812 | data->recout.y += (surf_clip.y - stream->src.y) * stream->dst.height |
| 804 | / stream->src.height; | 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 | data->recout.height = surf_clip.height * stream->dst.height / stream->src.height; | 817 | data->recout.height = surf_clip.height * stream->dst.height / stream->src.height; |
| 807 | if (data->recout.height + data->recout.y > stream->dst.y + stream->dst.height) | 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 | free_pipe->clock_source = tail_pipe->clock_source; | 1490 | free_pipe->clock_source = tail_pipe->clock_source; |
| 1480 | free_pipe->top_pipe = tail_pipe; | 1491 | free_pipe->top_pipe = tail_pipe; |
| 1481 | tail_pipe->bottom_pipe = free_pipe; | 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 | head_pipe = head_pipe->next_odm_pipe; | 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 | /* Add ABM to the resource if on EDP */ | 2148 | /* Add ABM to the resource if on EDP */ |
| 2130 | if (pipe_ctx->stream && dc_is_embedded_signal(pipe_ctx->stream->signal)) { | 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 | if (pool->abm) | 2151 | if (pool->abm) |
| 2133 | pipe_ctx->stream_res.abm = pool->abm; | 2152 | pipe_ctx->stream_res.abm = pool->abm; |
| 2134 | else | 2153 | else |
| @@ -2953,7 +2972,7 @@ unsigned int resource_pixel_format_to_bpp(enum surface_pixel_format format) · 818 unmodified lines | |||
| 2953 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: | 2972 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: |
| 2954 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: | 2973 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: |
| 2955 | case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS: | 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 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE: | 2976 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE: |
| 2958 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA: | 2977 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA: |
| 2959 | #endif | 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 | sink->ctx = link->ctx; | 54 | sink->ctx = link->ctx; |
| 55 | sink->dongle_max_pix_clk = init_params->dongle_max_pix_clk; | 55 | sink->dongle_max_pix_clk = init_params->dongle_max_pix_clk; |
| 56 | sink->converter_disable_audio = init_params->converter_disable_audio; | 56 | sink->converter_disable_audio = init_params->converter_disable_audio; |
| 57 | sink->is_mst_legacy = init_params->sink_is_legacy; | ||
| 58 | sink->dc_container_id = NULL; | 57 | sink->dc_container_id = NULL; |
| 59 | sink->sink_id = init_params->link->ctx->dc_sink_id_count; | 58 | sink->sink_id = init_params->link->ctx->dc_sink_id_count; |
| 60 | // increment dc_sink_id_count because we don't want two sinks with same ID | 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 | struct dc *dc; | 272 | struct dc *dc; |
| 273 | struct resource_context *res_ctx; | 273 | struct resource_context *res_ctx; |
| 274 | struct pipe_ctx *pipe_to_program = NULL; | 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 | bool reset_idle_optimizations = false; | 276 | bool reset_idle_optimizations = false; |
| 277 | #endif | 277 | #endif |
| 278 | 278 | ||
| @@ -294,7 +294,7 @@ bool dc_stream_set_cursor_attributes( · 15 unmodified lines | |||
| 294 | res_ctx = &dc->current_state->res_ctx; | 294 | res_ctx = &dc->current_state->res_ctx; |
| 295 | stream->cursor_attributes = *attributes; | 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 | /* disable idle optimizations while updating cursor */ | 298 | /* disable idle optimizations while updating cursor */ |
| 299 | if (dc->idle_optimizations_allowed) { | 299 | if (dc->idle_optimizations_allowed) { |
| 300 | dc_allow_idle_optimizations(dc, false); | 300 | dc_allow_idle_optimizations(dc, false); |
| @@ -322,7 +322,7 @@ bool dc_stream_set_cursor_attributes( · 21 unmodified lines | |||
| 322 | if (pipe_to_program) | 322 | if (pipe_to_program) |
| 323 | dc->hwss.cursor_lock(dc, pipe_to_program, false); | 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 | /* re-enable idle optimizations if necessary */ | 326 | /* re-enable idle optimizations if necessary */ |
| 327 | if (reset_idle_optimizations) | 327 | if (reset_idle_optimizations) |
| 328 | dc_allow_idle_optimizations(dc, true); | 328 | dc_allow_idle_optimizations(dc, true); |
| @@ -339,7 +339,7 @@ bool dc_stream_set_cursor_position( · 10 unmodified lines | |||
| 339 | struct dc *dc; | 339 | struct dc *dc; |
| 340 | struct resource_context *res_ctx; | 340 | struct resource_context *res_ctx; |
| 341 | struct pipe_ctx *pipe_to_program = NULL; | 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 | bool reset_idle_optimizations = false; | 343 | bool reset_idle_optimizations = false; |
| 344 | #endif | 344 | #endif |
| 345 | 345 | ||
| @@ -355,7 +355,7 @@ bool dc_stream_set_cursor_position( · 9 unmodified lines | |||
| 355 | 355 | ||
| 356 | dc = stream->ctx->dc; | 356 | dc = stream->ctx->dc; |
| 357 | res_ctx = &dc->current_state->res_ctx; | 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 | /* disable idle optimizations if enabling cursor */ | 360 | /* disable idle optimizations if enabling cursor */ |
| 361 | if (dc->idle_optimizations_allowed && !stream->cursor_position.enable && position->enable) { | 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 | if (pipe_to_program) | 387 | if (pipe_to_program) |
| 388 | dc->hwss.cursor_lock(dc, pipe_to_program, false); | 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 | /* re-enable idle optimizations if necessary */ | 391 | /* re-enable idle optimizations if necessary */ |
| 392 | if (reset_idle_optimizations) | 392 | if (reset_idle_optimizations) |
| 393 | dc_allow_idle_optimizations(dc, true); | 393 | dc_allow_idle_optimizations(dc, true); |
| @@ -42,7 +42,7 @@ · 41 unmodified lines | |||
| 42 | #include "inc/hw/dmcu.h" | 42 | #include "inc/hw/dmcu.h" |
| 43 | #include "dml/display_mode_lib.h" | 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 | #define MAX_SURFACES 3 | 47 | #define MAX_SURFACES 3 |
| 48 | #define MAX_PLANES 6 | 48 | #define MAX_PLANES 6 |
| @@ -152,9 +152,11 @@ struct dc_caps { · 103 unmodified lines | |||
| 152 | uint32_t max_planes; | 152 | uint32_t max_planes; |
| 153 | uint32_t max_downscale_ratio; | 153 | uint32_t max_downscale_ratio; |
| 154 | uint32_t i2c_speed_in_khz; | 154 | uint32_t i2c_speed_in_khz; |
| 155 | uint32_t i2c_speed_in_khz_hdcp; | ||
| 155 | uint32_t dmdata_alloc_size; | 156 | uint32_t dmdata_alloc_size; |
| 156 | unsigned int max_cursor_size; | 157 | unsigned int max_cursor_size; |
| 157 | unsigned int max_video_width; | 158 | unsigned int max_video_width; |
| 159 | unsigned int min_horizontal_blanking_period; | ||
| 158 | int linear_pitch_alignment; | 160 | int linear_pitch_alignment; |
| 159 | bool dcc_const_color; | 161 | bool dcc_const_color; |
| 160 | bool dynamic_audio; | 162 | bool dynamic_audio; |
| @@ -189,7 +191,7 @@ struct dc_dcc_setting { · 28 unmodified lines | |||
| 189 | unsigned int max_compressed_blk_size; | 191 | unsigned int max_compressed_blk_size; |
| 190 | unsigned int max_uncompressed_blk_size; | 192 | unsigned int max_uncompressed_blk_size; |
| 191 | bool independent_64b_blks; | 193 | bool independent_64b_blks; |
| 192 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | 194 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| 193 | //These bitfields to be used starting with DCN 3.0 | 195 | //These bitfields to be used starting with DCN 3.0 |
| 194 | struct { | 196 | struct { |
| 195 | uint32_t dcc_256_64_64 : 1;//available in ASICs before DCN 3.0 (the worst compression case) | 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 | bool multi_mon_pp_mclk_switch; | 292 | bool multi_mon_pp_mclk_switch; |
| 291 | bool disable_dmcu; | 293 | bool disable_dmcu; |
| 292 | bool enable_4to1MPC; | 294 | bool enable_4to1MPC; |
| 293 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | 295 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| 294 | bool clamp_min_dcfclk; | 296 | bool clamp_min_dcfclk; |
| 295 | #endif | 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 | struct dc_debug_options { | 425 | struct dc_debug_options { |
| 416 | enum visual_confirm visual_confirm; | 426 | enum visual_confirm visual_confirm; |
| 417 | bool sanity_checks; | 427 | bool sanity_checks; |
| @@ -472,14 +482,14 @@ struct dc_debug_options { · 54 unmodified lines | |||
| 472 | bool edid_read_retry_times; | 482 | bool edid_read_retry_times; |
| 473 | bool remove_disconnect_edp; | 483 | bool remove_disconnect_edp; |
| 474 | unsigned int force_odm_combine; //bit vector based on otg inst | 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 | unsigned int force_odm_combine_4to1; //bit vector based on otg inst | 486 | unsigned int force_odm_combine_4to1; //bit vector based on otg inst |
| 477 | #endif | 487 | #endif |
| 478 | unsigned int force_fclk_khz; | 488 | unsigned int force_fclk_khz; |
| 479 | bool enable_tri_buf; | 489 | bool enable_tri_buf; |
| 480 | bool dmub_offload_enabled; | 490 | bool dmub_offload_enabled; |
| 481 | bool dmcub_emulation; | 491 | bool dmcub_emulation; |
| 482 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | 492 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| 483 | bool disable_idle_power_optimizations; | 493 | bool disable_idle_power_optimizations; |
| 484 | #endif | 494 | #endif |
| 485 | bool dmub_command_table; /* for testing only */ | 495 | bool dmub_command_table; /* for testing only */ |
| @@ -490,7 +500,7 @@ struct dc_debug_options { · 4 unmodified lines | |||
| 490 | * watermarks are not affected. | 500 | * watermarks are not affected. |
| 491 | */ | 501 | */ |
| 492 | unsigned int force_min_dcfclk_mhz; | 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 | int dwb_fi_phase; | 504 | int dwb_fi_phase; |
| 495 | #endif | 505 | #endif |
| 496 | bool disable_timing_sync; | 506 | bool disable_timing_sync; |
| @@ -504,6 +514,7 @@ struct dc_debug_options { · 7 unmodified lines | |||
| 504 | bool disable_dsc; | 514 | bool disable_dsc; |
| 505 | bool enable_dram_clock_change_one_display_vactive; | 515 | bool enable_dram_clock_change_one_display_vactive; |
| 506 | bool force_ignore_link_settings; | 516 | bool force_ignore_link_settings; |
| 517 | union mem_low_power_enable_options enable_mem_low_power; | ||
| 507 | }; | 518 | }; |
| 508 | 519 | ||
| 509 | struct dc_debug_data { | 520 | struct dc_debug_data { |
| @@ -599,7 +610,7 @@ struct dc { · 89 unmodified lines | |||
| 599 | /* Require to optimize clocks and bandwidth for added/removed planes */ | 610 | /* Require to optimize clocks and bandwidth for added/removed planes */ |
| 600 | bool optimized_required; | 611 | bool optimized_required; |
| 601 | bool wm_optimized_required; | 612 | bool wm_optimized_required; |
| 602 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | 613 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| 603 | bool idle_optimizations_allowed; | 614 | bool idle_optimizations_allowed; |
| 604 | #endif | 615 | #endif |
| 605 | 616 | ||
| @@ -658,7 +669,7 @@ struct dc_init_data { · 52 unmodified lines | |||
| 658 | */ | 669 | */ |
| 659 | const struct gpu_info_soc_bounding_box_v1_0 *soc_bounding_box; | 670 | const struct gpu_info_soc_bounding_box_v1_0 *soc_bounding_box; |
| 660 | struct dpcd_vendor_signature vendor_signature; | 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 | bool force_smu_not_present; | 673 | bool force_smu_not_present; |
| 663 | #endif | 674 | #endif |
| 664 | bool force_ignore_link_settings; | 675 | bool force_ignore_link_settings; |
| @@ -853,7 +864,7 @@ struct dc_plane_state { · 188 unmodified lines | |||
| 853 | struct dc_transfer_func *in_shaper_func; | 864 | struct dc_transfer_func *in_shaper_func; |
| 854 | struct dc_transfer_func *blend_tf; | 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 | struct dc_transfer_func *gamcor_tf; | 868 | struct dc_transfer_func *gamcor_tf; |
| 858 | #endif | 869 | #endif |
| 859 | enum surface_pixel_format format; | 870 | enum surface_pixel_format format; |
| @@ -962,7 +973,7 @@ struct dc_flip_addrs { · 102 unmodified lines | |||
| 962 | bool triplebuffer_flips; | 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 | struct dc *dc); | 977 | struct dc *dc); |
| 967 | 978 | ||
| 968 | #include "dc_stream.h" | 979 | #include "dc_stream.h" |
| @@ -1001,7 +1012,7 @@ void dc_resource_state_construct( · 32 unmodified lines | |||
| 1001 | const struct dc *dc, | 1012 | const struct dc *dc, |
| 1002 | struct dc_state *dst_ctx); | 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 | bool dc_acquire_release_mpc_3dlut( | 1016 | bool dc_acquire_release_mpc_3dlut( |
| 1006 | struct dc *dc, bool acquire, | 1017 | struct dc *dc, bool acquire, |
| 1007 | struct dc_stream_state *stream, | 1018 | struct dc_stream_state *stream, |
| @@ -1129,7 +1140,7 @@ struct hdcp_caps { · 121 unmodified lines | |||
| 1129 | 1140 | ||
| 1130 | #include "dc_link.h" | 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 | uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane); | 1144 | uint32_t dc_get_opp_for_plane(struct dc *dc, struct dc_plane_state *plane); |
| 1134 | 1145 | ||
| 1135 | #endif | 1146 | #endif |
| @@ -1173,7 +1184,7 @@ struct dc_sink { · 37 unmodified lines | |||
| 1173 | void *priv; | 1184 | void *priv; |
| 1174 | struct stereo_3d_features features_3d[TIMING_3D_FORMAT_MAX]; | 1185 | struct stereo_3d_features features_3d[TIMING_3D_FORMAT_MAX]; |
| 1175 | bool converter_disable_audio; | 1186 | bool converter_disable_audio; |
| 1176 | bool is_mst_legacy; | 1187 | |
| 1177 | struct dc_sink_dsc_caps dsc_caps; | 1188 | struct dc_sink_dsc_caps dsc_caps; |
| 1178 | struct dc_sink_fec_caps fec_caps; | 1189 | struct dc_sink_fec_caps fec_caps; |
| 1179 | 1190 | ||
| @@ -1200,7 +1211,6 @@ struct dc_sink_init_data { · 20 unmodified lines | |||
| 1200 | struct dc_link *link; | 1211 | struct dc_link *link; |
| 1201 | uint32_t dongle_max_pix_clk; | 1212 | uint32_t dongle_max_pix_clk; |
| 1202 | bool converter_disable_audio; | 1213 | bool converter_disable_audio; |
| 1203 | bool sink_is_legacy; | ||
| 1204 | }; | 1214 | }; |
| 1205 | 1215 | ||
| 1206 | struct dc_sink *dc_sink_create(const struct dc_sink_init_data *init_params); | 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 | enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping); | 1259 | enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping); |
| 1250 | void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_config *clock_cfg); | 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 | bool dc_is_plane_eligible_for_idle_optimizations(struct dc *dc, | 1263 | bool dc_is_plane_eligible_for_idle_optimizations(struct dc *dc, |
| 1254 | struct dc_plane_state *plane); | 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 | void dc_lock_memory_clock_frequency(struct dc *dc); | 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 | #endif | 1283 | #endif |
| 1271 | 1284 | ||
| 1272 | bool dc_set_psr_allow_active(struct dc *dc, bool enable); | 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 | bool dc_dsc_compute_bandwidth_range( | 62 | bool dc_dsc_compute_bandwidth_range( |
| 63 | const struct display_stream_compressor *dsc, | 63 | const struct display_stream_compressor *dsc, |
| 64 | const uint32_t dsc_min_slice_height_override, | 64 | uint32_t dsc_min_slice_height_override, |
| 65 | const uint32_t min_bpp, | 65 | uint32_t min_bpp, |
| 66 | const uint32_t max_bpp, | 66 | uint32_t max_bpp, |
| 67 | const struct dsc_dec_dpcd_caps *dsc_sink_caps, | 67 | const struct dsc_dec_dpcd_caps *dsc_sink_caps, |
| 68 | const struct dc_crtc_timing *timing, | 68 | const struct dc_crtc_timing *timing, |
| 69 | struct dc_dsc_bw_range *range); | 69 | struct dc_dsc_bw_range *range); |
| @@ -71,12 +71,14 @@ bool dc_dsc_compute_bandwidth_range( · 1 unmodified line | |||
| 71 | bool dc_dsc_compute_config( | 71 | bool dc_dsc_compute_config( |
| 72 | const struct display_stream_compressor *dsc, | 72 | const struct display_stream_compressor *dsc, |
| 73 | const struct dsc_dec_dpcd_caps *dsc_sink_caps, | 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 | uint32_t target_bandwidth_kbps, | 76 | uint32_t target_bandwidth_kbps, |
| 76 | const struct dc_crtc_timing *timing, | 77 | const struct dc_crtc_timing *timing, |
| 77 | struct dc_dsc_config *dsc_cfg); | 78 | struct dc_dsc_config *dsc_cfg); |
| 78 | 79 | ||
| 79 | void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, | 80 | void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, |
| 81 | uint32_t max_target_bpp_limit_override, | ||
| 80 | struct dc_dsc_policy *policy); | 82 | struct dc_dsc_policy *policy); |
| 81 | 83 | ||
| 82 | void dc_dsc_policy_set_max_target_bpp_limit(uint32_t limit); | 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 | return reg_val; | 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 | uint32_t generic_reg_get(const struct dc_context *ctx, uint32_t addr, | 299 | uint32_t generic_reg_get(const struct dc_context *ctx, uint32_t addr, |
| 326 | uint8_t shift, uint32_t mask, uint32_t *field_value) | 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 | PLN_ADDR_TYPE_GRAPHICS = 0, | 62 | PLN_ADDR_TYPE_GRAPHICS = 0, |
| 63 | PLN_ADDR_TYPE_GRPH_STEREO, | 63 | PLN_ADDR_TYPE_GRPH_STEREO, |
| 64 | PLN_ADDR_TYPE_VIDEO_PROGRESSIVE, | 64 | PLN_ADDR_TYPE_VIDEO_PROGRESSIVE, |
| 65 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 66 | PLN_ADDR_TYPE_RGBEA | 65 | PLN_ADDR_TYPE_RGBEA |
| 67 | #endif | ||
| 68 | }; | 66 | }; |
| 69 | 67 | ||
| 70 | struct dc_plane_address { | 68 | struct dc_plane_address { |
| @@ -87,7 +85,6 @@ struct dc_plane_address { · 16 unmodified lines | |||
| 87 | PHYSICAL_ADDRESS_LOC right_meta_addr; | 85 | PHYSICAL_ADDRESS_LOC right_meta_addr; |
| 88 | union large_integer right_dcc_const_color; | 86 | union large_integer right_dcc_const_color; |
| 89 | 87 | ||
| 90 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 91 | PHYSICAL_ADDRESS_LOC left_alpha_addr; | 88 | PHYSICAL_ADDRESS_LOC left_alpha_addr; |
| 92 | PHYSICAL_ADDRESS_LOC left_alpha_meta_addr; | 89 | PHYSICAL_ADDRESS_LOC left_alpha_meta_addr; |
| 93 | union large_integer left_alpha_dcc_const_color; | 90 | union large_integer left_alpha_dcc_const_color; |
| @@ -95,7 +92,6 @@ struct dc_plane_address { · 1 unmodified line | |||
| 95 | PHYSICAL_ADDRESS_LOC right_alpha_addr; | 92 | PHYSICAL_ADDRESS_LOC right_alpha_addr; |
| 96 | PHYSICAL_ADDRESS_LOC right_alpha_meta_addr; | 93 | PHYSICAL_ADDRESS_LOC right_alpha_meta_addr; |
| 97 | union large_integer right_alpha_dcc_const_color; | 94 | union large_integer right_alpha_dcc_const_color; |
| 98 | #endif | ||
| 99 | 95 | ||
| 100 | } grph_stereo; | 96 | } grph_stereo; |
| 101 | 97 | ||
| @@ -110,7 +106,6 @@ struct dc_plane_address { · 8 unmodified lines | |||
| 110 | union large_integer chroma_dcc_const_color; | 106 | union large_integer chroma_dcc_const_color; |
| 111 | } video_progressive; | 107 | } video_progressive; |
| 112 | 108 | ||
| 113 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 114 | struct { | 109 | struct { |
| 115 | PHYSICAL_ADDRESS_LOC addr; | 110 | PHYSICAL_ADDRESS_LOC addr; |
| 116 | PHYSICAL_ADDRESS_LOC meta_addr; | 111 | PHYSICAL_ADDRESS_LOC meta_addr; |
| @@ -120,7 +115,6 @@ struct dc_plane_address { · 3 unmodified lines | |||
| 120 | PHYSICAL_ADDRESS_LOC alpha_meta_addr; | 115 | PHYSICAL_ADDRESS_LOC alpha_meta_addr; |
| 121 | union large_integer alpha_dcc_const_color; | 116 | union large_integer alpha_dcc_const_color; |
| 122 | } rgbea; | 117 | } rgbea; |
| 123 | #endif | ||
| 124 | }; | 118 | }; |
| 125 | 119 | ||
| 126 | union large_integer page_table_base; | 120 | union large_integer page_table_base; |
| @@ -156,15 +150,11 @@ struct dc_plane_dcc_param { · 29 unmodified lines | |||
| 156 | 150 | ||
| 157 | int meta_pitch; | 151 | int meta_pitch; |
| 158 | bool independent_64b_blks; | 152 | bool independent_64b_blks; |
| 159 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 160 | uint8_t dcc_ind_blk; | 153 | uint8_t dcc_ind_blk; |
| 161 | #endif | ||
| 162 | 154 | ||
| 163 | int meta_pitch_c; | 155 | int meta_pitch_c; |
| 164 | bool independent_64b_blks_c; | 156 | bool independent_64b_blks_c; |
| 165 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 166 | uint8_t dcc_ind_blk_c; | 157 | uint8_t dcc_ind_blk_c; |
| 167 | #endif | ||
| 168 | }; | 158 | }; |
| 169 | 159 | ||
| 170 | /*Displayable pixel format in fb*/ | 160 | /*Displayable pixel format in fb*/ |
| @@ -200,10 +190,8 @@ enum surface_pixel_format { · 29 unmodified lines | |||
| 200 | SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX, | 190 | SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX, |
| 201 | SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT, | 191 | SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT, |
| 202 | SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT, | 192 | SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT, |
| 203 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 204 | SURFACE_PIXEL_FORMAT_GRPH_RGBE, | 193 | SURFACE_PIXEL_FORMAT_GRPH_RGBE, |
| 205 | SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA, | 194 | SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA, |
| 206 | #endif | ||
| 207 | SURFACE_PIXEL_FORMAT_VIDEO_BEGIN, | 195 | SURFACE_PIXEL_FORMAT_VIDEO_BEGIN, |
| 208 | SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr = | 196 | SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr = |
| 209 | SURFACE_PIXEL_FORMAT_VIDEO_BEGIN, | 197 | SURFACE_PIXEL_FORMAT_VIDEO_BEGIN, |
| @@ -856,8 +844,6 @@ enum dwb_stereo_type { · 646 unmodified lines | |||
| 856 | DWB_STEREO_TYPE_FRAME_SEQUENTIAL = 3, /* Frame sequential */ | 844 | DWB_STEREO_TYPE_FRAME_SEQUENTIAL = 3, /* Frame sequential */ |
| 857 | }; | 845 | }; |
| 858 | 846 | ||
| 859 | #ifdef CONFIG_DRM_AMD_DC_DCN3_0 | ||
| 860 | |||
| 861 | enum dwb_out_format { | 847 | enum dwb_out_format { |
| 862 | DWB_OUT_FORMAT_32BPP_ARGB = 0, | 848 | DWB_OUT_FORMAT_32BPP_ARGB = 0, |
| 863 | DWB_OUT_FORMAT_32BPP_RGBA = 1, | 849 | DWB_OUT_FORMAT_32BPP_RGBA = 1, |
| @@ -890,8 +876,6 @@ struct mcif_warmup_params { · 26 unmodified lines | |||
| 890 | unsigned int p_vmid; | 876 | unsigned int p_vmid; |
| 891 | }; | 877 | }; |
| 892 | 878 | ||
| 893 | #endif | ||
| 894 | |||
| 895 | #define MCIF_BUF_COUNT 4 | 879 | #define MCIF_BUF_COUNT 4 |
| 896 | 880 | ||
| 897 | struct mcif_buf_params { | 881 | struct mcif_buf_params { |
| @@ -901,9 +885,7 @@ struct mcif_buf_params { · 3 unmodified lines | |||
| 901 | unsigned int chroma_pitch; | 885 | unsigned int chroma_pitch; |
| 902 | unsigned int warmup_pitch; | 886 | unsigned int warmup_pitch; |
| 903 | unsigned int swlock; | 887 | unsigned int swlock; |
| 904 | #ifdef CONFIG_DRM_AMD_DC_DCN3_0 | ||
| 905 | unsigned int p_vmid; | 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 | int audio_inst; | 45 | int audio_inst; |
| 46 | struct timing_sync_info timing_sync_info; | 46 | struct timing_sync_info timing_sync_info; |
| 47 | struct dc_plane_state *plane_states[MAX_SURFACE_NUM]; | 47 | struct dc_plane_state *plane_states[MAX_SURFACE_NUM]; |
| 48 | bool is_abm_supported; | ||
| 48 | }; | 49 | }; |
| 49 | 50 | ||
| 50 | // TODO: References to this needs to be removed.. | 51 | // TODO: References to this needs to be removed.. |
| @@ -87,13 +88,11 @@ struct dc_writeback_info { · 36 unmodified lines | |||
| 87 | int dwb_pipe_inst; | 88 | int dwb_pipe_inst; |
| 88 | struct dc_dwb_params dwb_params; | 89 | struct dc_dwb_params dwb_params; |
| 89 | struct mcif_buf_params mcif_buf_params; | 90 | struct mcif_buf_params mcif_buf_params; |
| 90 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 91 | struct mcif_warmup_params mcif_warmup_params; | 91 | struct mcif_warmup_params mcif_warmup_params; |
| 92 | /* the plane that is the input to TOP_MUX for MPCC that is the DWB source */ | 92 | /* the plane that is the input to TOP_MUX for MPCC that is the DWB source */ |
| 93 | struct dc_plane_state *writeback_source_plane; | 93 | struct dc_plane_state *writeback_source_plane; |
| 94 | /* source MPCC instance. for use by internally by dc */ | 94 | /* source MPCC instance. for use by internally by dc */ |
| 95 | int mpcc_inst; | 95 | int mpcc_inst; |
| 96 | #endif | ||
| 97 | }; | 96 | }; |
| 98 | 97 | ||
| 99 | struct dc_writeback_update { | 98 | struct dc_writeback_update { |
| @@ -207,10 +206,8 @@ struct dc_stream_state { · 107 unmodified lines | |||
| 207 | /* writeback */ | 206 | /* writeback */ |
| 208 | unsigned int num_wb_info; | 207 | unsigned int num_wb_info; |
| 209 | struct dc_writeback_info writeback_info[MAX_DWB_PIPES]; | 208 | struct dc_writeback_info writeback_info[MAX_DWB_PIPES]; |
| 210 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 211 | const struct dc_transfer_func *func_shaper; | 209 | const struct dc_transfer_func *func_shaper; |
| 212 | const struct dc_3dlut *lut3d_func; | 210 | const struct dc_3dlut *lut3d_func; |
| 213 | #endif | ||
| 214 | /* Computed state bits */ | 211 | /* Computed state bits */ |
| 215 | bool mode_changed : 1; | 212 | bool mode_changed : 1; |
| 216 | 213 | ||
| @@ -262,10 +259,8 @@ struct dc_stream_update { · 45 unmodified lines | |||
| 262 | 259 | ||
| 263 | struct dc_writeback_update *wb_update; | 260 | struct dc_writeback_update *wb_update; |
| 264 | struct dc_dsc_config *dsc_config; | 261 | struct dc_dsc_config *dsc_config; |
| 265 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 266 | struct dc_transfer_func *func_shaper; | 262 | struct dc_transfer_func *func_shaper; |
| 267 | struct dc_3dlut *lut3d_func; | 263 | struct dc_3dlut *lut3d_func; |
| 268 | #endif | ||
| 269 | }; | 264 | }; |
| 270 | 265 | ||
| 271 | bool dc_is_stream_unchanged( | 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 | * Enable stereo when commit_streams is not required, | 386 | * Enable stereo when commit_streams is not required, |
| 392 | * for example, frame alternate. | 387 | * for example, frame alternate. |
| 393 | */ | 388 | */ |
| 394 | bool dc_enable_stereo( | 389 | void dc_enable_stereo( |
| 395 | struct dc *dc, | 390 | struct dc *dc, |
| 396 | struct dc_state *context, | 391 | struct dc_state *context, |
| 397 | struct dc_stream_state *streams[], | 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 | bool dc_stream_configure_crc(struct dc *dc, | 452 | bool dc_stream_configure_crc(struct dc *dc, |
| 458 | struct dc_stream_state *stream, | 453 | struct dc_stream_state *stream, |
| 454 | struct crc_params *crc_window, | ||
| 459 | bool enable, | 455 | bool enable, |
| 460 | bool continuous); | 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 | unsigned int delay_ignore_msa; | 234 | unsigned int delay_ignore_msa; |
| 235 | unsigned int disable_fec; | 235 | unsigned int disable_fec; |
| 236 | unsigned int extra_t3_ms; | 236 | unsigned int extra_t3_ms; |
| 237 | unsigned int max_dsc_target_bpp_limit; | ||
| 238 | unsigned int skip_avmute; | ||
| 237 | }; | 239 | }; |
| 238 | 240 | ||
| 239 | struct dc_edid_caps { | 241 | struct dc_edid_caps { |
| @@ -479,7 +481,6 @@ enum display_content_type { · 239 unmodified lines | |||
| 479 | DISPLAY_CONTENT_TYPE_GAME = 8 | 481 | DISPLAY_CONTENT_TYPE_GAME = 8 |
| 480 | }; | 482 | }; |
| 481 | 483 | ||
| 482 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 483 | enum cm_gamut_adjust_type { | 484 | enum cm_gamut_adjust_type { |
| 484 | CM_GAMUT_ADJUST_TYPE_BYPASS = 0, | 485 | CM_GAMUT_ADJUST_TYPE_BYPASS = 0, |
| 485 | CM_GAMUT_ADJUST_TYPE_HW, /* without adjustments */ | 486 | CM_GAMUT_ADJUST_TYPE_HW, /* without adjustments */ |
| @@ -491,7 +492,7 @@ struct cm_grph_csc_adjustment { · 5 unmodified lines | |||
| 491 | enum cm_gamut_adjust_type gamut_adjust_type; | 492 | enum cm_gamut_adjust_type gamut_adjust_type; |
| 492 | enum cm_gamut_coef_format gamut_coef_format; | 493 | enum cm_gamut_coef_format gamut_coef_format; |
| 493 | }; | 494 | }; |
| 494 | #endif | 495 | |
| 495 | /* writeback */ | 496 | /* writeback */ |
| 496 | struct dwb_stereo_params { | 497 | struct dwb_stereo_params { |
| 497 | bool stereo_enabled; /* false: normal mode, true: 3D stereo */ | 498 | bool stereo_enabled; /* false: normal mode, true: 3D stereo */ |
| @@ -509,21 +510,17 @@ struct dc_dwb_cnv_params { · 11 unmodified lines | |||
| 509 | unsigned int crop_x; /* cropped window start x value at cnv output */ | 510 | unsigned int crop_x; /* cropped window start x value at cnv output */ |
| 510 | unsigned int crop_y; /* cropped window start y value at cnv output */ | 511 | unsigned int crop_y; /* cropped window start y value at cnv output */ |
| 511 | enum dwb_cnv_out_bpc cnv_out_bpc; /* cnv output pixel depth - 8bpc or 10bpc */ | 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 | enum dwb_out_format fc_out_format; /* dwb output pixel format - 2101010 or 16161616 and ARGB or RGBA */ | 513 | enum dwb_out_format fc_out_format; /* dwb output pixel format - 2101010 or 16161616 and ARGB or RGBA */ |
| 514 | enum dwb_out_denorm out_denorm_mode;/* dwb output denormalization mode */ | 514 | enum dwb_out_denorm out_denorm_mode;/* dwb output denormalization mode */ |
| 515 | unsigned int out_max_pix_val;/* pixel values greater than out_max_pix_val are clamped to out_max_pix_val */ | 515 | unsigned int out_max_pix_val;/* pixel values greater than out_max_pix_val are clamped to out_max_pix_val */ |
| 516 | unsigned int out_min_pix_val;/* pixel values less than out_min_pix_val are clamped to out_min_pix_val */ | 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 | struct dc_dwb_params { | 519 | struct dc_dwb_params { |
| 521 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 522 | unsigned int dwbscl_black_color; /* must be in FP1.5.10 */ | 520 | unsigned int dwbscl_black_color; /* must be in FP1.5.10 */ |
| 523 | unsigned int hdr_mult; /* must be in FP1.6.12 */ | 521 | unsigned int hdr_mult; /* must be in FP1.6.12 */ |
| 524 | struct cm_grph_csc_adjustment csc_params; | 522 | struct cm_grph_csc_adjustment csc_params; |
| 525 | struct dwb_stereo_params stereo_params; | 523 | struct dwb_stereo_params stereo_params; |
| 526 | #endif | ||
| 527 | struct dc_dwb_cnv_params cnv_params; /* CNV source size and cropping window parameters */ | 524 | struct dc_dwb_cnv_params cnv_params; /* CNV source size and cropping window parameters */ |
| 528 | unsigned int dest_width; /* Destination width */ | 525 | unsigned int dest_width; /* Destination width */ |
| 529 | unsigned int dest_height; /* Destination height */ | 526 | unsigned int dest_height; /* Destination height */ |
| @@ -904,8 +901,6 @@ struct dc_golden_table { · 374 unmodified lines | |||
| 904 | uint32_t dc_gpio_aux_ctrl_5_val; | 901 | uint32_t dc_gpio_aux_ctrl_5_val; |
| 905 | }; | 902 | }; |
| 906 | 903 | ||
| 907 | |||
| 908 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 909 | enum dc_gpu_mem_alloc_type { | 904 | enum dc_gpu_mem_alloc_type { |
| 910 | DC_MEM_ALLOC_TYPE_GART, | 905 | DC_MEM_ALLOC_TYPE_GART, |
| 911 | DC_MEM_ALLOC_TYPE_FRAME_BUFFER, | 906 | DC_MEM_ALLOC_TYPE_FRAME_BUFFER, |
| @@ -913,7 +908,6 @@ enum dc_gpu_mem_alloc_type { · 1 unmodified line | |||
| 913 | DC_MEM_ALLOC_TYPE_AGP | 908 | DC_MEM_ALLOC_TYPE_AGP |
| 914 | }; | 909 | }; |
| 915 | 910 | ||
| 916 | #endif | ||
| 917 | enum dc_psr_version { | 911 | enum dc_psr_version { |
| 918 | DC_PSR_VERSION_1 = 0, | 912 | DC_PSR_VERSION_1 = 0, |
| 919 | DC_PSR_VERSION_UNSUPPORTED = 0xFFFFFFFF, | 913 | DC_PSR_VERSION_UNSUPPORTED = 0xFFFFFFFF, |
| @@ -82,7 +82,20 @@ · 81 unmodified lines | |||
| 82 | SR(DC_ABM1_ACE_THRES_12), \ | 82 | SR(DC_ABM1_ACE_THRES_12), \ |
| 83 | NBIO_SR(BIOS_SCRATCH_2) | 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 | #define ABM_DCN30_REG_LIST(id)\ | 99 | #define ABM_DCN30_REG_LIST(id)\ |
| 87 | ABM_COMMON_REG_LIST_DCE_BASE(), \ | 100 | ABM_COMMON_REG_LIST_DCE_BASE(), \ |
| 88 | SRI(DC_ABM1_HG_SAMPLE_RATE, ABM, id), \ | 101 | SRI(DC_ABM1_HG_SAMPLE_RATE, ABM, id), \ |
| @@ -98,7 +111,6 @@ · 9 unmodified lines | |||
| 98 | SRI(DC_ABM1_ACE_OFFSET_SLOPE_0, ABM, id), \ | 111 | SRI(DC_ABM1_ACE_OFFSET_SLOPE_0, ABM, id), \ |
| 99 | SRI(DC_ABM1_ACE_THRES_12, ABM, id), \ | 112 | SRI(DC_ABM1_ACE_THRES_12, ABM, id), \ |
| 100 | NBIO_SR(BIOS_SCRATCH_2) | 113 | NBIO_SR(BIOS_SCRATCH_2) |
| 101 | #endif | ||
| 102 | 114 | ||
| 103 | #define ABM_SF(reg_name, field_name, post_fix)\ | 115 | #define ABM_SF(reg_name, field_name, post_fix)\ |
| 104 | .field_name = reg_name ## __ ## field_name ## post_fix | 116 | .field_name = reg_name ## __ ## field_name ## post_fix |
| @@ -173,9 +185,7 @@ · 68 unmodified lines | |||
| 173 | 185 | ||
| 174 | #define ABM_MASK_SH_LIST_DCN20(mask_sh) ABM_MASK_SH_LIST_DCE110(mask_sh) | 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) | 188 | #define ABM_MASK_SH_LIST_DCN30(mask_sh) ABM_MASK_SH_LIST_DCN10(mask_sh) |
| 177 | #define ABM_MASK_SH_LIST_DCN301(mask_sh) ABM_MASK_SH_LIST_DCN10(mask_sh) | ||
| 178 | #endif | ||
| 179 | 189 | ||
| 180 | #define ABM_REG_FIELD_LIST(type) \ | 190 | #define ABM_REG_FIELD_LIST(type) \ |
| 181 | type ABM1_HG_NUM_OF_BINS_SEL; \ | 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 | } else { | 652 | } else { |
| 653 | if ((*payload->reply == AUX_TRANSACTION_REPLY_AUX_DEFER) || | 653 | if ((*payload->reply == AUX_TRANSACTION_REPLY_AUX_DEFER) || |
| 654 | (*payload->reply == AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER)) { | 654 | (*payload->reply == AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER)) { |
| 655 | if (payload->defer_delay > 0) | 655 | if (payload->defer_delay > 1) |
| 656 | msleep(payload->defer_delay); | 656 | msleep(payload->defer_delay); |
| 657 | else if (payload->defer_delay <= 1) | ||
| 658 | udelay(payload->defer_delay * 1000); | ||
| 657 | } | 659 | } |
| 658 | } | 660 | } |
| 659 | break; | 661 | break; |
| @@ -317,7 +317,9 @@ int dce112_set_clock(struct clk_mgr *clk_mgr, int requested_clk_khz) · 316 unmodified lines | |||
| 317 | /*VBIOS will determine DPREFCLK frequency, so we don't set it*/ | 317 | /*VBIOS will determine DPREFCLK frequency, so we don't set it*/ |
| 318 | dce_clk_params.target_clock_frequency = 0; | 318 | dce_clk_params.target_clock_frequency = 0; |
| 319 | dce_clk_params.clock_type = DCECLOCK_TYPE_DPREFCLK; | 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 | dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = | 323 | dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK = |
| 322 | (dce_clk_params.pll_id == | 324 | (dce_clk_params.pll_id == |
| 323 | CLOCK_SOURCE_COMBO_DISPLAY_PLL0); | 325 | CLOCK_SOURCE_COMBO_DISPLAY_PLL0); |
| @@ -1004,7 +1004,7 @@ static bool get_pixel_clk_frequency_100hz( · 1003 unmodified lines | |||
| 1004 | return false; | 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 | /* this table is use to find *1.001 and /1.001 pixel rates from non-precise pixel rate */ | 1008 | /* this table is use to find *1.001 and /1.001 pixel rates from non-precise pixel rate */ |
| 1009 | const struct pixel_rate_range_table_entry video_optimized_pixel_rates[] = { | 1009 | const struct pixel_rate_range_table_entry video_optimized_pixel_rates[] = { |
| 1010 | // /1.001 rates | 1010 | // /1.001 rates |
| @@ -1073,7 +1073,7 @@ static const struct clock_source_funcs dcn20_clk_src_funcs = { · 62 unmodified lines | |||
| 1073 | .get_pixel_clk_frequency_100hz = get_pixel_clk_frequency_100hz | 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 | static bool dcn3_program_pix_clk( | 1077 | static bool dcn3_program_pix_clk( |
| 1078 | struct clock_source *clock_source, | 1078 | struct clock_source *clock_source, |
| 1079 | struct pixel_clk_params *pix_clk_params, | 1079 | struct pixel_clk_params *pix_clk_params, |
| @@ -1538,7 +1538,7 @@ bool dcn20_clk_src_construct( · 458 unmodified lines | |||
| 1538 | return ret; | 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 | bool dcn3_clk_src_construct( | 1542 | bool dcn3_clk_src_construct( |
| 1543 | struct dce110_clk_src *clk_src, | 1543 | struct dce110_clk_src *clk_src, |
| 1544 | struct dc_context *ctx, | 1544 | struct dc_context *ctx, |
| @@ -1555,3 +1555,21 @@ bool dcn3_clk_src_construct( · 10 unmodified lines | |||
| 1555 | return ret; | 1555 | return ret; |
| 1556 | } | 1556 | } |
| 1557 | #endif | 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 | SRII(PIXEL_RATE_CNTL, OTG, 2),\ | 91 | SRII(PIXEL_RATE_CNTL, OTG, 2),\ |
| 92 | SRII(PIXEL_RATE_CNTL, OTG, 3) | 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 | #define CS_COMMON_REG_LIST_DCN3_0(index, pllid) \ | 95 | #define CS_COMMON_REG_LIST_DCN3_0(index, pllid) \ |
| 96 | SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\ | 96 | SRI(PIXCLK_RESYNC_CNTL, PHYPLL, pllid),\ |
| 97 | SRII(PHASE, DP_DTO, 0),\ | 97 | SRII(PHASE, DP_DTO, 0),\ |
| @@ -106,8 +106,43 @@ · 8 unmodified lines | |||
| 106 | SRII(PIXEL_RATE_CNTL, OTG, 1),\ | 106 | SRII(PIXEL_RATE_CNTL, OTG, 1),\ |
| 107 | SRII(PIXEL_RATE_CNTL, OTG, 2),\ | 107 | SRII(PIXEL_RATE_CNTL, OTG, 2),\ |
| 108 | SRII(PIXEL_RATE_CNTL, OTG, 3) | 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 | #endif | 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 | #define CS_COMMON_MASK_SH_LIST_DCN2_0(mask_sh)\ | 146 | #define CS_COMMON_MASK_SH_LIST_DCN2_0(mask_sh)\ |
| 112 | CS_SF(DP_DTO0_PHASE, DP_DTO0_PHASE, mask_sh),\ | 147 | CS_SF(DP_DTO0_PHASE, DP_DTO0_PHASE, mask_sh),\ |
| 113 | CS_SF(DP_DTO0_MODULO, DP_DTO0_MODULO, mask_sh),\ | 148 | CS_SF(DP_DTO0_MODULO, DP_DTO0_MODULO, mask_sh),\ |
| @@ -221,7 +256,7 @@ bool dcn20_clk_src_construct( · 107 unmodified lines | |||
| 221 | const struct dce110_clk_src_shift *cs_shift, | 256 | const struct dce110_clk_src_shift *cs_shift, |
| 222 | const struct dce110_clk_src_mask *cs_mask); | 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 | bool dcn3_clk_src_construct( | 260 | bool dcn3_clk_src_construct( |
| 226 | struct dce110_clk_src *clk_src, | 261 | struct dce110_clk_src *clk_src, |
| 227 | struct dc_context *ctx, | 262 | struct dc_context *ctx, |
| @@ -230,6 +265,15 @@ bool dcn3_clk_src_construct( · 2 unmodified lines | |||
| 230 | const struct dce110_clk_src_regs *regs, | 265 | const struct dce110_clk_src_regs *regs, |
| 231 | const struct dce110_clk_src_shift *cs_shift, | 266 | const struct dce110_clk_src_shift *cs_shift, |
| 232 | const struct dce110_clk_src_mask *cs_mask); | 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 | #endif | 277 | #endif |
| 234 | 278 | ||
| 235 | /* this table is use to find *1.001 and /1.001 pixel rates from non-precise pixel rate */ | 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 | unsigned short div_factor; | 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 | extern const struct pixel_rate_range_table_entry video_optimized_pixel_rates[]; | 289 | extern const struct pixel_rate_range_table_entry video_optimized_pixel_rates[]; |
| 246 | const struct pixel_rate_range_table_entry *look_up_in_video_optimized_rate_tlb( | 290 | const struct pixel_rate_range_table_entry *look_up_in_video_optimized_rate_tlb( |
| 247 | unsigned int pixel_rate_khz); | 291 | unsigned int pixel_rate_khz); |
| 248 | #endif | 292 | #endif |
| 293 | |||
| 249 | #endif | 294 | #endif |
| @@ -78,7 +78,6 @@ · 77 unmodified lines | |||
| 78 | SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4), \ | 78 | SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4), \ |
| 79 | SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 5) | 79 | SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 5) |
| 80 | 80 | ||
| 81 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 82 | #define HWSEQ_PIXEL_RATE_REG_LIST_3(blk) \ | 81 | #define HWSEQ_PIXEL_RATE_REG_LIST_3(blk) \ |
| 83 | SRII(PIXEL_RATE_CNTL, blk, 0), \ | 82 | SRII(PIXEL_RATE_CNTL, blk, 0), \ |
| 84 | SRII(PIXEL_RATE_CNTL, blk, 1),\ | 83 | SRII(PIXEL_RATE_CNTL, blk, 1),\ |
| @@ -94,7 +93,6 @@ · 9 unmodified lines | |||
| 94 | SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 3), \ | 93 | SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 3), \ |
| 95 | SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4), \ | 94 | SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 4), \ |
| 96 | SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 5) | 95 | SRII(PHYPLL_PIXEL_RATE_CNTL, blk, 5) |
| 97 | #endif | ||
| 98 | 96 | ||
| 99 | #define HWSEQ_DCE11_REG_LIST_BASE() \ | 97 | #define HWSEQ_DCE11_REG_LIST_BASE() \ |
| 100 | SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \ | 98 | SR(DC_MEM_GLOBAL_PWR_REQ_CNTL), \ |
| @@ -224,28 +222,6 @@ · 123 unmodified lines | |||
| 224 | SR(VGA_TEST_CONTROL), \ | 222 | SR(VGA_TEST_CONTROL), \ |
| 225 | SR(DC_IP_REQUEST_CNTL) | 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 | #define HWSEQ_DCN2_REG_LIST()\ | 225 | #define HWSEQ_DCN2_REG_LIST()\ |
| 250 | HWSEQ_DCN_REG_LIST(), \ | 226 | HWSEQ_DCN_REG_LIST(), \ |
| 251 | HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 0), \ | 227 | HSWEQ_DCN_PIXEL_RATE_REG_LIST(OTG, 0), \ |
| @@ -361,6 +337,163 @@ · 109 unmodified lines | |||
| 361 | SR(D6VGA_CONTROL), \ | 337 | SR(D6VGA_CONTROL), \ |
| 362 | SR(DC_IP_REQUEST_CNTL) | 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 | struct dce_hwseq_registers { | 497 | struct dce_hwseq_registers { |
| 365 | uint32_t DCFE_CLOCK_CONTROL[6]; | 498 | uint32_t DCFE_CLOCK_CONTROL[6]; |
| 366 | uint32_t DCFEV_CLOCK_CONTROL; | 499 | uint32_t DCFEV_CLOCK_CONTROL; |
| @@ -462,6 +595,8 @@ struct dce_hwseq_registers { · 95 unmodified lines | |||
| 462 | uint32_t MC_VM_XGMI_LFB_CNTL; | 595 | uint32_t MC_VM_XGMI_LFB_CNTL; |
| 463 | uint32_t AZALIA_AUDIO_DTO; | 596 | uint32_t AZALIA_AUDIO_DTO; |
| 464 | uint32_t AZALIA_CONTROLLER_CLOCK_GATING; | 597 | uint32_t AZALIA_CONTROLLER_CLOCK_GATING; |
| 598 | uint32_t HPO_TOP_CLOCK_CONTROL; | ||
| 599 | uint32_t ODM_MEM_PWR_CTRL3; | ||
| 465 | }; | 600 | }; |
| 466 | /* set field name */ | 601 | /* set field name */ |
| 467 | #define HWS_SF(blk_name, reg_name, field_name, post_fix)\ | 602 | #define HWS_SF(blk_name, reg_name, field_name, post_fix)\ |
| @@ -598,12 +733,6 @@ struct dce_hwseq_registers { · 130 unmodified lines | |||
| 598 | HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_ENABLE, mask_sh),\ | 733 | HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_ENABLE, mask_sh),\ |
| 599 | HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_RENDER_START, mask_sh) | 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 | #define HWSEQ_DCN2_MASK_SH_LIST(mask_sh)\ | 736 | #define HWSEQ_DCN2_MASK_SH_LIST(mask_sh)\ |
| 608 | HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ | 737 | HWSEQ_DCN_MASK_SH_LIST(mask_sh), \ |
| 609 | HWS_SF(, DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, mask_sh), \ | 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 | HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \ | 832 | HWS_SF(, DOMAIN18_PG_STATUS, DOMAIN18_PGFSM_PWR_STATUS, mask_sh), \ |
| 704 | HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh) | 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 | #define HWSEQ_REG_FIELD_LIST(type) \ | 935 | #define HWSEQ_REG_FIELD_LIST(type) \ |
| 707 | type DCFE_CLOCK_ENABLE; \ | 936 | type DCFE_CLOCK_ENABLE; \ |
| 708 | type DCFEV_CLOCK_ENABLE; \ | 937 | type DCFEV_CLOCK_ENABLE; \ |
| @@ -815,16 +1044,31 @@ struct dce_hwseq_registers { · 106 unmodified lines | |||
| 815 | type D2VGA_MODE_ENABLE; \ | 1044 | type D2VGA_MODE_ENABLE; \ |
| 816 | type D3VGA_MODE_ENABLE; \ | 1045 | type D3VGA_MODE_ENABLE; \ |
| 817 | type D4VGA_MODE_ENABLE; \ | 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 | struct dce_hwseq_shift { | 1060 | struct dce_hwseq_shift { |
| 821 | HWSEQ_REG_FIELD_LIST(uint8_t) | 1061 | HWSEQ_REG_FIELD_LIST(uint8_t) |
| 822 | HWSEQ_DCN_REG_FIELD_LIST(uint8_t) | 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 | struct dce_hwseq_mask { | 1067 | struct dce_hwseq_mask { |
| 826 | HWSEQ_REG_FIELD_LIST(uint32_t) | 1068 | HWSEQ_REG_FIELD_LIST(uint32_t) |
| 827 | HWSEQ_DCN_REG_FIELD_LIST(uint32_t) | 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 | /* we have checked I2c not used by DMCU, set SW use I2C REQ to 1 to indicate SW using it*/ | 299 | /* we have checked I2c not used by DMCU, set SW use I2C REQ to 1 to indicate SW using it*/ |
| 300 | REG_UPDATE(DC_I2C_ARBITRATION, DC_I2C_SW_USE_I2C_REG_REQ, 1); | 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 | if (dce_i2c_hw->setup_limit != 0) | 305 | if (dce_i2c_hw->setup_limit != 0) |
| 303 | i2c_setup_limit = dce_i2c_hw->setup_limit; | 306 | i2c_setup_limit = dce_i2c_hw->setup_limit; |
| 307 | |||
| 304 | /* Program pin select */ | 308 | /* Program pin select */ |
| 305 | REG_UPDATE_6(DC_I2C_CONTROL, | 309 | REG_UPDATE_6(DC_I2C_CONTROL, |
| 306 | DC_I2C_GO, 0, | 310 | DC_I2C_GO, 0, |
| @@ -339,8 +343,6 @@ static void release_engine( · 32 unmodified lines | |||
| 339 | { | 343 | { |
| 340 | bool safe_to_reset; | 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 | /* Reset HW engine */ | 347 | /* Reset HW engine */ |
| 346 | { | 348 | { |
| @@ -360,6 +362,9 @@ static void release_engine( · 13 unmodified lines | |||
| 360 | /* HW I2c engine - clock gating feature */ | 362 | /* HW I2c engine - clock gating feature */ |
| 361 | if (!dce_i2c_hw->engine_keep_power_up_count) | 363 | if (!dce_i2c_hw->engine_keep_power_up_count) |
| 362 | REG_UPDATE_N(SETUP, 1, FN(SETUP, DC_I2C_DDC1_ENABLE), 0); | 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 | /* Release I2C after reset, so HW or DMCU could use it */ | 368 | /* Release I2C after reset, so HW or DMCU could use it */ |
| 364 | REG_UPDATE_2(DC_I2C_ARBITRATION, DC_I2C_SW_DONE_USING_I2C_REG, 1, | 369 | REG_UPDATE_2(DC_I2C_ARBITRATION, DC_I2C_SW_DONE_USING_I2C_REG, 1, |
| 365 | DC_I2C_SW_USE_I2C_REG_REQ, 0); | 370 | DC_I2C_SW_USE_I2C_REG_REQ, 0); |
| @@ -1330,7 +1330,6 @@ static bool configure_graphics_mode( · 1329 unmodified lines | |||
| 1330 | REG_SET(OUTPUT_CSC_CONTROL, 0, | 1330 | REG_SET(OUTPUT_CSC_CONTROL, 0, |
| 1331 | OUTPUT_CSC_GRPH_MODE, 0); | 1331 | OUTPUT_CSC_GRPH_MODE, 0); |
| 1332 | break; | 1332 | break; |
| 1333 | break; | ||
| 1334 | case COLOR_SPACE_SRGB_LIMITED: | 1333 | case COLOR_SPACE_SRGB_LIMITED: |
| 1335 | /* TV RGB */ | 1334 | /* TV RGB */ |
| 1336 | REG_SET(OUTPUT_CSC_CONTROL, 0, | 1335 | REG_SET(OUTPUT_CSC_CONTROL, 0, |
| @@ -418,25 +418,18 @@ static int map_transmitter_id_to_phy_instance( · 417 unmodified lines | |||
| 418 | switch (transmitter) { | 418 | switch (transmitter) { |
| 419 | case TRANSMITTER_UNIPHY_A: | 419 | case TRANSMITTER_UNIPHY_A: |
| 420 | return 0; | 420 | return 0; |
| 421 | break; | ||
| 422 | case TRANSMITTER_UNIPHY_B: | 421 | case TRANSMITTER_UNIPHY_B: |
| 423 | return 1; | 422 | return 1; |
| 424 | break; | ||
| 425 | case TRANSMITTER_UNIPHY_C: | 423 | case TRANSMITTER_UNIPHY_C: |
| 426 | return 2; | 424 | return 2; |
| 427 | break; | ||
| 428 | case TRANSMITTER_UNIPHY_D: | 425 | case TRANSMITTER_UNIPHY_D: |
| 429 | return 3; | 426 | return 3; |
| 430 | break; | ||
| 431 | case TRANSMITTER_UNIPHY_E: | 427 | case TRANSMITTER_UNIPHY_E: |
| 432 | return 4; | 428 | return 4; |
| 433 | break; | ||
| 434 | case TRANSMITTER_UNIPHY_F: | 429 | case TRANSMITTER_UNIPHY_F: |
| 435 | return 5; | 430 | return 5; |
| 436 | break; | ||
| 437 | case TRANSMITTER_UNIPHY_G: | 431 | case TRANSMITTER_UNIPHY_G: |
| 438 | return 6; | 432 | return 6; |
| 439 | break; | ||
| 440 | default: | 433 | default: |
| 441 | ASSERT(0); | 434 | ASSERT(0); |
| 442 | return 0; | 435 | return 0; |
| @@ -1071,7 +1064,9 @@ static bool dce100_resource_construct( · 628 unmodified lines | |||
| 1071 | pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator; | 1064 | pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator; |
| 1072 | dc->caps.max_downscale_ratio = 200; | 1065 | dc->caps.max_downscale_ratio = 200; |
| 1073 | dc->caps.i2c_speed_in_khz = 40; | 1066 | dc->caps.i2c_speed_in_khz = 40; |
| 1067 | dc->caps.i2c_speed_in_khz = 40; | ||
| 1074 | dc->caps.max_cursor_size = 128; | 1068 | dc->caps.max_cursor_size = 128; |
| 1069 | dc->caps.min_horizontal_blanking_period = 80; | ||
| 1075 | dc->caps.dual_link_dvi = true; | 1070 | dc->caps.dual_link_dvi = true; |
| 1076 | dc->caps.disable_dp_clk_share = true; | 1071 | dc->caps.disable_dp_clk_share = true; |
| 1077 | dc->caps.extended_aux_timeout_support = false; | 1072 | dc->caps.extended_aux_timeout_support = false; |
| @@ -992,8 +992,6 @@ void dce110_edp_backlight_control( · 991 unmodified lines | |||
| 992 | 992 | ||
| 993 | link_transmitter_control(ctx->dc_bios, &cntl); | 993 | link_transmitter_control(ctx->dc_bios, &cntl); |
| 994 | 994 | ||
| 995 | |||
| 996 | |||
| 997 | if (enable && link->dpcd_sink_ext_caps.bits.oled) | 995 | if (enable && link->dpcd_sink_ext_caps.bits.oled) |
| 998 | msleep(OLED_POST_T7_DELAY); | 996 | msleep(OLED_POST_T7_DELAY); |
| 999 | 997 | ||
| @@ -1004,7 +1002,7 @@ void dce110_edp_backlight_control( · 4 unmodified lines | |||
| 1004 | 1002 | ||
| 1005 | /*edp 1.2*/ | 1003 | /*edp 1.2*/ |
| 1006 | if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_OFF) | 1004 | if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_OFF) |
| 1007 | edp_receiver_ready_T9(link); | 1005 | edp_add_delay_for_T9(link); |
| 1008 | 1006 | ||
| 1009 | if (!enable && link->dpcd_sink_ext_caps.bits.oled) | 1007 | if (!enable && link->dpcd_sink_ext_caps.bits.oled) |
| 1010 | msleep(OLED_PRE_T11_DELAY); | 1008 | msleep(OLED_PRE_T11_DELAY); |
| @@ -1145,12 +1143,14 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx) · 134 unmodified lines | |||
| 1145 | if (dc_is_dp_signal(pipe_ctx->stream->signal)) { | 1143 | if (dc_is_dp_signal(pipe_ctx->stream->signal)) { |
| 1146 | pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc); | 1144 | pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc); |
| 1147 | 1145 | ||
| 1148 | /* | 1146 | if (!dc_is_embedded_signal(pipe_ctx->stream->signal)) { |
| 1149 | * After output is idle pattern some sinks need time to recognize the stream | 1147 | /* |
| 1150 | * has changed or they enter protection state and hang. | 1148 | * After output is idle pattern some sinks need time to recognize the stream |
| 1151 | */ | 1149 | * has changed or they enter protection state and hang. |
| 1152 | if (!dc_is_embedded_signal(pipe_ctx->stream->signal)) | 1150 | */ |
| 1153 | msleep(60); | 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 | switch (transmitter) { | 471 | switch (transmitter) { |
| 472 | case TRANSMITTER_UNIPHY_A: | 472 | case TRANSMITTER_UNIPHY_A: |
| 473 | return 0; | 473 | return 0; |
| 474 | break; | ||
| 475 | case TRANSMITTER_UNIPHY_B: | 474 | case TRANSMITTER_UNIPHY_B: |
| 476 | return 1; | 475 | return 1; |
| 477 | break; | ||
| 478 | case TRANSMITTER_UNIPHY_C: | 476 | case TRANSMITTER_UNIPHY_C: |
| 479 | return 2; | 477 | return 2; |
| 480 | break; | ||
| 481 | case TRANSMITTER_UNIPHY_D: | 478 | case TRANSMITTER_UNIPHY_D: |
| 482 | return 3; | 479 | return 3; |
| 483 | break; | ||
| 484 | case TRANSMITTER_UNIPHY_E: | 480 | case TRANSMITTER_UNIPHY_E: |
| 485 | return 4; | 481 | return 4; |
| 486 | break; | ||
| 487 | case TRANSMITTER_UNIPHY_F: | 482 | case TRANSMITTER_UNIPHY_F: |
| 488 | return 5; | 483 | return 5; |
| 489 | break; | ||
| 490 | case TRANSMITTER_UNIPHY_G: | 484 | case TRANSMITTER_UNIPHY_G: |
| 491 | return 6; | 485 | return 6; |
| 492 | break; | ||
| 493 | default: | 486 | default: |
| 494 | ASSERT(0); | 487 | ASSERT(0); |
| 495 | return 0; | 488 | return 0; |
| @@ -1372,8 +1365,10 @@ static bool dce110_resource_construct( · 876 unmodified lines | |||
| 1372 | pool->base.underlay_pipe_index = pool->base.pipe_count; | 1365 | pool->base.underlay_pipe_index = pool->base.pipe_count; |
| 1373 | pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator; | 1366 | pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator; |
| 1374 | dc->caps.max_downscale_ratio = 150; | 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 | dc->caps.max_cursor_size = 128; | 1370 | dc->caps.max_cursor_size = 128; |
| 1371 | dc->caps.min_horizontal_blanking_period = 80; | ||
| 1377 | dc->caps.is_apu = true; | 1372 | dc->caps.is_apu = true; |
| 1378 | dc->caps.extended_aux_timeout_support = false; | 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 | switch (transmitter) { | 446 | switch (transmitter) { |
| 447 | case TRANSMITTER_UNIPHY_A: | 447 | case TRANSMITTER_UNIPHY_A: |
| 448 | return 0; | 448 | return 0; |
| 449 | break; | ||
| 450 | case TRANSMITTER_UNIPHY_B: | 449 | case TRANSMITTER_UNIPHY_B: |
| 451 | return 1; | 450 | return 1; |
| 452 | break; | ||
| 453 | case TRANSMITTER_UNIPHY_C: | 451 | case TRANSMITTER_UNIPHY_C: |
| 454 | return 2; | 452 | return 2; |
| 455 | break; | ||
| 456 | case TRANSMITTER_UNIPHY_D: | 453 | case TRANSMITTER_UNIPHY_D: |
| 457 | return 3; | 454 | return 3; |
| 458 | break; | ||
| 459 | case TRANSMITTER_UNIPHY_E: | 455 | case TRANSMITTER_UNIPHY_E: |
| 460 | return 4; | 456 | return 4; |
| 461 | break; | ||
| 462 | case TRANSMITTER_UNIPHY_F: | 457 | case TRANSMITTER_UNIPHY_F: |
| 463 | return 5; | 458 | return 5; |
| 464 | break; | ||
| 465 | case TRANSMITTER_UNIPHY_G: | 459 | case TRANSMITTER_UNIPHY_G: |
| 466 | return 6; | 460 | return 6; |
| 467 | break; | ||
| 468 | default: | 461 | default: |
| 469 | ASSERT(0); | 462 | ASSERT(0); |
| 470 | return 0; | 463 | return 0; |
| @@ -865,7 +858,7 @@ static struct clock_source *find_matching_pll( · 394 unmodified lines | |||
| 865 | return pool->clock_sources[DCE112_CLK_SRC_PLL5]; | 858 | return pool->clock_sources[DCE112_CLK_SRC_PLL5]; |
| 866 | default: | 859 | default: |
| 867 | return NULL; | 860 | return NULL; |
| 868 | }; | 861 | } |
| 869 | 862 | ||
| 870 | return 0; | 863 | return 0; |
| 871 | } | 864 | } |
| @@ -1240,7 +1233,9 @@ static bool dce112_resource_construct( · 368 unmodified lines | |||
| 1240 | pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator; | 1233 | pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator; |
| 1241 | dc->caps.max_downscale_ratio = 200; | 1234 | dc->caps.max_downscale_ratio = 200; |
| 1242 | dc->caps.i2c_speed_in_khz = 100; | 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 | dc->caps.max_cursor_size = 128; | 1237 | dc->caps.max_cursor_size = 128; |
| 1238 | dc->caps.min_horizontal_blanking_period = 80; | ||
| 1244 | dc->caps.dual_link_dvi = true; | 1239 | dc->caps.dual_link_dvi = true; |
| 1245 | dc->caps.extended_aux_timeout_support = false; | 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 | switch (transmitter) { | 383 | switch (transmitter) { |
| 384 | case TRANSMITTER_UNIPHY_A: | 384 | case TRANSMITTER_UNIPHY_A: |
| 385 | return 0; | 385 | return 0; |
| 386 | break; | ||
| 387 | case TRANSMITTER_UNIPHY_B: | 386 | case TRANSMITTER_UNIPHY_B: |
| 388 | return 1; | 387 | return 1; |
| 389 | break; | ||
| 390 | case TRANSMITTER_UNIPHY_C: | 388 | case TRANSMITTER_UNIPHY_C: |
| 391 | return 2; | 389 | return 2; |
| 392 | break; | ||
| 393 | case TRANSMITTER_UNIPHY_D: | 390 | case TRANSMITTER_UNIPHY_D: |
| 394 | return 3; | 391 | return 3; |
| 395 | break; | ||
| 396 | case TRANSMITTER_UNIPHY_E: | 392 | case TRANSMITTER_UNIPHY_E: |
| 397 | return 4; | 393 | return 4; |
| 398 | break; | ||
| 399 | case TRANSMITTER_UNIPHY_F: | 394 | case TRANSMITTER_UNIPHY_F: |
| 400 | return 5; | 395 | return 5; |
| 401 | break; | ||
| 402 | case TRANSMITTER_UNIPHY_G: | 396 | case TRANSMITTER_UNIPHY_G: |
| 403 | return 6; | 397 | return 6; |
| 404 | break; | ||
| 405 | default: | 398 | default: |
| 406 | ASSERT(0); | 399 | ASSERT(0); |
| 407 | return 0; | 400 | return 0; |
| @@ -1080,7 +1073,9 @@ static bool dce120_resource_construct( · 672 unmodified lines | |||
| 1080 | 1073 | ||
| 1081 | dc->caps.max_downscale_ratio = 200; | 1074 | dc->caps.max_downscale_ratio = 200; |
| 1082 | dc->caps.i2c_speed_in_khz = 100; | 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 | dc->caps.max_cursor_size = 128; | 1077 | dc->caps.max_cursor_size = 128; |
| 1078 | dc->caps.min_horizontal_blanking_period = 80; | ||
| 1084 | dc->caps.dual_link_dvi = true; | 1079 | dc->caps.dual_link_dvi = true; |
| 1085 | dc->caps.psp_setup_panel_mode = true; | 1080 | dc->caps.psp_setup_panel_mode = true; |
| 1086 | dc->caps.extended_aux_timeout_support = false; | 1081 | dc->caps.extended_aux_timeout_support = false; |
| @@ -453,25 +453,18 @@ static int map_transmitter_id_to_phy_instance( · 452 unmodified lines | |||
| 453 | switch (transmitter) { | 453 | switch (transmitter) { |
| 454 | case TRANSMITTER_UNIPHY_A: | 454 | case TRANSMITTER_UNIPHY_A: |
| 455 | return 0; | 455 | return 0; |
| 456 | break; | ||
| 457 | case TRANSMITTER_UNIPHY_B: | 456 | case TRANSMITTER_UNIPHY_B: |
| 458 | return 1; | 457 | return 1; |
| 459 | break; | ||
| 460 | case TRANSMITTER_UNIPHY_C: | 458 | case TRANSMITTER_UNIPHY_C: |
| 461 | return 2; | 459 | return 2; |
| 462 | break; | ||
| 463 | case TRANSMITTER_UNIPHY_D: | 460 | case TRANSMITTER_UNIPHY_D: |
| 464 | return 3; | 461 | return 3; |
| 465 | break; | ||
| 466 | case TRANSMITTER_UNIPHY_E: | 462 | case TRANSMITTER_UNIPHY_E: |
| 467 | return 4; | 463 | return 4; |
| 468 | break; | ||
| 469 | case TRANSMITTER_UNIPHY_F: | 464 | case TRANSMITTER_UNIPHY_F: |
| 470 | return 5; | 465 | return 5; |
| 471 | break; | ||
| 472 | case TRANSMITTER_UNIPHY_G: | 466 | case TRANSMITTER_UNIPHY_G: |
| 473 | return 6; | 467 | return 6; |
| 474 | break; | ||
| 475 | default: | 468 | default: |
| 476 | ASSERT(0); | 469 | ASSERT(0); |
| 477 | return 0; | 470 | return 0; |
| @@ -458,25 +458,18 @@ static int map_transmitter_id_to_phy_instance( · 457 unmodified lines | |||
| 458 | switch (transmitter) { | 458 | switch (transmitter) { |
| 459 | case TRANSMITTER_UNIPHY_A: | 459 | case TRANSMITTER_UNIPHY_A: |
| 460 | return 0; | 460 | return 0; |
| 461 | break; | ||
| 462 | case TRANSMITTER_UNIPHY_B: | 461 | case TRANSMITTER_UNIPHY_B: |
| 463 | return 1; | 462 | return 1; |
| 464 | break; | ||
| 465 | case TRANSMITTER_UNIPHY_C: | 463 | case TRANSMITTER_UNIPHY_C: |
| 466 | return 2; | 464 | return 2; |
| 467 | break; | ||
| 468 | case TRANSMITTER_UNIPHY_D: | 465 | case TRANSMITTER_UNIPHY_D: |
| 469 | return 3; | 466 | return 3; |
| 470 | break; | ||
| 471 | case TRANSMITTER_UNIPHY_E: | 467 | case TRANSMITTER_UNIPHY_E: |
| 472 | return 4; | 468 | return 4; |
| 473 | break; | ||
| 474 | case TRANSMITTER_UNIPHY_F: | 469 | case TRANSMITTER_UNIPHY_F: |
| 475 | return 5; | 470 | return 5; |
| 476 | break; | ||
| 477 | case TRANSMITTER_UNIPHY_G: | 471 | case TRANSMITTER_UNIPHY_G: |
| 478 | return 6; | 472 | return 6; |
| 479 | break; | ||
| 480 | default: | 473 | default: |
| 481 | ASSERT(0); | 474 | ASSERT(0); |
| 482 | return 0; | 475 | return 0; |
| @@ -970,7 +963,9 @@ static bool dce80_construct( · 487 unmodified lines | |||
| 970 | pool->base.timing_generator_count = res_cap.num_timing_generator; | 963 | pool->base.timing_generator_count = res_cap.num_timing_generator; |
| 971 | dc->caps.max_downscale_ratio = 200; | 964 | dc->caps.max_downscale_ratio = 200; |
| 972 | dc->caps.i2c_speed_in_khz = 40; | 965 | dc->caps.i2c_speed_in_khz = 40; |
| 966 | dc->caps.i2c_speed_in_khz_hdcp = 40; | ||
| 973 | dc->caps.max_cursor_size = 128; | 967 | dc->caps.max_cursor_size = 128; |
| 968 | dc->caps.min_horizontal_blanking_period = 80; | ||
| 974 | dc->caps.dual_link_dvi = true; | 969 | dc->caps.dual_link_dvi = true; |
| 975 | dc->caps.extended_aux_timeout_support = false; | 970 | dc->caps.extended_aux_timeout_support = false; |
| 976 | 971 | ||
| @@ -1168,7 +1163,9 @@ static bool dce81_construct( · 191 unmodified lines | |||
| 1168 | pool->base.timing_generator_count = res_cap_81.num_timing_generator; | 1163 | pool->base.timing_generator_count = res_cap_81.num_timing_generator; |
| 1169 | dc->caps.max_downscale_ratio = 200; | 1164 | dc->caps.max_downscale_ratio = 200; |
| 1170 | dc->caps.i2c_speed_in_khz = 40; | 1165 | dc->caps.i2c_speed_in_khz = 40; |
| 1166 | dc->caps.i2c_speed_in_khz_hdcp = 40; | ||
| 1171 | dc->caps.max_cursor_size = 128; | 1167 | dc->caps.max_cursor_size = 128; |
| 1168 | dc->caps.min_horizontal_blanking_period = 80; | ||
| 1172 | dc->caps.is_apu = true; | 1169 | dc->caps.is_apu = true; |
| 1173 | 1170 | ||
| 1174 | /************************************************* | 1171 | /************************************************* |
| @@ -1365,7 +1362,9 @@ static bool dce83_construct( · 190 unmodified lines | |||
| 1365 | pool->base.timing_generator_count = res_cap_83.num_timing_generator; | 1362 | pool->base.timing_generator_count = res_cap_83.num_timing_generator; |
| 1366 | dc->caps.max_downscale_ratio = 200; | 1363 | dc->caps.max_downscale_ratio = 200; |
| 1367 | dc->caps.i2c_speed_in_khz = 40; | 1364 | dc->caps.i2c_speed_in_khz = 40; |
| 1365 | dc->caps.i2c_speed_in_khz_hdcp = 40; | ||
| 1368 | dc->caps.max_cursor_size = 128; | 1366 | dc->caps.max_cursor_size = 128; |
| 1367 | dc->caps.min_horizontal_blanking_period = 80; | ||
| 1369 | dc->caps.is_apu = true; | 1368 | dc->caps.is_apu = true; |
| 1370 | 1369 | ||
| 1371 | /************************************************* | 1370 | /************************************************* |
| @@ -656,7 +656,7 @@ static void dpp1_dscl_set_recout( · 655 unmodified lines | |||
| 656 | RECOUT_WIDTH, recout->width, | 656 | RECOUT_WIDTH, recout->width, |
| 657 | /* Number of RECOUT vertical lines */ | 657 | /* Number of RECOUT vertical lines */ |
| 658 | RECOUT_HEIGHT, recout->height | 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 | /* Main function to program scaler and line buffer in manual scaling mode */ | 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 | REG_UPDATE(DCSURF_SURFACE_CONFIG, | 326 | REG_UPDATE(DCSURF_SURFACE_CONFIG, |
| 327 | SURFACE_PIXEL_FORMAT, 119); | 327 | SURFACE_PIXEL_FORMAT, 119); |
| 328 | break; | 328 | break; |
| 329 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 330 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE: | 329 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE: |
| 331 | REG_UPDATE_2(DCSURF_SURFACE_CONFIG, | 330 | REG_UPDATE_2(DCSURF_SURFACE_CONFIG, |
| 332 | SURFACE_PIXEL_FORMAT, 116, | 331 | SURFACE_PIXEL_FORMAT, 116, |
| @@ -337,7 +336,6 @@ void hubp1_program_pixel_format( · 4 unmodified lines | |||
| 337 | SURFACE_PIXEL_FORMAT, 116, | 336 | SURFACE_PIXEL_FORMAT, 116, |
| 338 | ALPHA_PLANE_EN, 1); | 337 | ALPHA_PLANE_EN, 1); |
| 339 | break; | 338 | break; |
| 340 | #endif | ||
| 341 | default: | 339 | default: |
| 342 | BREAK_TO_DEBUGGER(); | 340 | BREAK_TO_DEBUGGER(); |
| 343 | break; | 341 | break; |
| @@ -52,6 +52,7 @@ · 51 unmodified lines | |||
| 52 | #include "dpcd_defs.h" | 52 | #include "dpcd_defs.h" |
| 53 | #include "dsc.h" | 53 | #include "dsc.h" |
| 54 | #include "dce/dmub_hw_lock_mgr.h" | 54 | #include "dce/dmub_hw_lock_mgr.h" |
| 55 | #include "dc_trace.h" | ||
| 55 | 56 | ||
| 56 | #define DC_LOGGER_INIT(logger) | 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 | void dcn10_verify_allow_pstate_change_high(struct dc *dc) | 1024 | void dcn10_verify_allow_pstate_change_high(struct dc *dc) |
| 1025 | { | 1025 | { |
| 1026 | static bool should_log_hw_state; /* prevent hw state log by default */ | 1026 | static bool should_log_hw_state; /* prevent hw state log by default */ |
| 1027 | 1027 | ||
| 1028 | if (!hubbub1_verify_allow_pstate_change_high(dc->res_pool->hubbub)) { | 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 | dcn10_log_hw_state(dc, NULL); | 1032 | dcn10_log_hw_state(dc, NULL); |
| 1031 | } | 1033 | |
| 1034 | TRACE_DC_PIPE_STATE(pipe_ctx, i, MAX_PIPES); | ||
| 1032 | BREAK_TO_DEBUGGER(); | 1035 | BREAK_TO_DEBUGGER(); |
| 1033 | if (dcn10_hw_wa_force_recovery(dc)) { | 1036 | if (dcn10_hw_wa_force_recovery(dc)) { |
| 1034 | /*check again*/ | 1037 | /*check again*/ |
| @@ -1434,12 +1437,6 @@ void dcn10_init_hw(struct dc *dc) · 399 unmodified lines | |||
| 1434 | 1437 | ||
| 1435 | if (dc->clk_mgr->funcs->notify_wm_ranges) | 1438 | if (dc->clk_mgr->funcs->notify_wm_ranges) |
| 1436 | dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr); | 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 | /* In headless boot cases, DIG may be turned | 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 | plane_state->address.type = PLN_ADDR_TYPE_GRPH_STEREO; | 1538 | plane_state->address.type = PLN_ADDR_TYPE_GRPH_STEREO; |
| 1542 | plane_state->address.grph_stereo.right_addr = | 1539 | plane_state->address.grph_stereo.right_addr = |
| 1543 | plane_state->address.grph_stereo.left_addr; | 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 | return false; | 1545 | return false; |
| @@ -1851,10 +1850,20 @@ void dcn10_enable_timing_synchronization( · 304 unmodified lines | |||
| 1851 | struct pipe_ctx *grouped_pipes[]) | 1850 | struct pipe_ctx *grouped_pipes[]) |
| 1852 | { | 1851 | { |
| 1853 | struct dc_context *dc_ctx = dc->ctx; | 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 | DC_SYNC_INFO("Setting up OTG reset trigger\n"); | 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 | for (i = 1; i < group_size; i++) | 1867 | for (i = 1; i < group_size; i++) |
| 1859 | grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger( | 1868 | grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger( |
| 1860 | grouped_pipes[i]->stream_res.tg, | 1869 | grouped_pipes[i]->stream_res.tg, |
| @@ -1871,6 +1880,14 @@ void dcn10_enable_timing_synchronization( · 10 unmodified lines | |||
| 1871 | grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger( | 1880 | grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger( |
| 1872 | grouped_pipes[i]->stream_res.tg); | 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 | DC_SYNC_INFO("Sync complete\n"); | 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 | return NULL; | 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 | void dcn10_wait_for_pending_cleared(struct dc *dc, | 2781 | void dcn10_wait_for_pending_cleared(struct dc *dc, |
| 2881 | struct dc_state *context) | 2782 | struct dc_state *context) |
| 2882 | { | 2783 | { |
| @@ -34,7 +34,6 @@ static const struct hw_sequencer_funcs dcn10_funcs = { · 33 unmodified lines | |||
| 34 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, | 34 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, |
| 35 | .apply_ctx_for_surface = dcn10_apply_ctx_for_surface, | 35 | .apply_ctx_for_surface = dcn10_apply_ctx_for_surface, |
| 36 | .post_unlock_program_front_end = dcn10_post_unlock_program_front_end, | 36 | .post_unlock_program_front_end = dcn10_post_unlock_program_front_end, |
| 37 | .disconnect_pipes = dcn10_disconnect_pipes, | ||
| 38 | .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, | 37 | .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, |
| 39 | .update_plane_addr = dcn10_update_plane_addr, | 38 | .update_plane_addr = dcn10_update_plane_addr, |
| 40 | .update_dchub = dcn10_update_dchub, | 39 | .update_dchub = dcn10_update_dchub, |
| @@ -154,12 +154,10 @@ struct dcn10_link_enc_registers { · 153 unmodified lines | |||
| 154 | uint32_t RAWLANE2_DIG_PCS_XF_RX_OVRD_IN_3; | 154 | uint32_t RAWLANE2_DIG_PCS_XF_RX_OVRD_IN_3; |
| 155 | uint32_t RAWLANE3_DIG_PCS_XF_RX_OVRD_IN_2; | 155 | uint32_t RAWLANE3_DIG_PCS_XF_RX_OVRD_IN_2; |
| 156 | uint32_t RAWLANE3_DIG_PCS_XF_RX_OVRD_IN_3; | 156 | uint32_t RAWLANE3_DIG_PCS_XF_RX_OVRD_IN_3; |
| 157 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 158 | uint32_t TMDS_DCBALANCER_CONTROL; | 157 | uint32_t TMDS_DCBALANCER_CONTROL; |
| 159 | uint32_t PHYA_LINK_CNTL2; | 158 | uint32_t PHYA_LINK_CNTL2; |
| 160 | uint32_t PHYB_LINK_CNTL2; | 159 | uint32_t PHYB_LINK_CNTL2; |
| 161 | uint32_t PHYC_LINK_CNTL2; | 160 | uint32_t PHYC_LINK_CNTL2; |
| 162 | #endif | ||
| 163 | }; | 161 | }; |
| 164 | 162 | ||
| 165 | #define LE_SF(reg_name, field_name, post_fix)\ | 163 | #define LE_SF(reg_name, field_name, post_fix)\ |
| @@ -449,14 +447,25 @@ struct dcn10_link_enc_registers { · 283 unmodified lines | |||
| 449 | type AUX_RX_TIMEOUT_LEN;\ | 447 | type AUX_RX_TIMEOUT_LEN;\ |
| 450 | type AUX_RX_TIMEOUT_LEN_MUL | 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 | struct dcn10_link_enc_shift { | 459 | struct dcn10_link_enc_shift { |
| 453 | DCN_LINK_ENCODER_REG_FIELD_LIST(uint8_t); | 460 | DCN_LINK_ENCODER_REG_FIELD_LIST(uint8_t); |
| 454 | DCN20_LINK_ENCODER_REG_FIELD_LIST(uint8_t); | 461 | DCN20_LINK_ENCODER_REG_FIELD_LIST(uint8_t); |
| 462 | DCN30_LINK_ENCODER_REG_FIELD_LIST(uint8_t); | ||
| 455 | }; | 463 | }; |
| 456 | 464 | ||
| 457 | struct dcn10_link_enc_mask { | 465 | struct dcn10_link_enc_mask { |
| 458 | DCN_LINK_ENCODER_REG_FIELD_LIST(uint32_t); | 466 | DCN_LINK_ENCODER_REG_FIELD_LIST(uint32_t); |
| 459 | DCN20_LINK_ENCODER_REG_FIELD_LIST(uint32_t); | 467 | DCN20_LINK_ENCODER_REG_FIELD_LIST(uint32_t); |
| 468 | DCN30_LINK_ENCODER_REG_FIELD_LIST(uint32_t); | ||
| 460 | }; | 469 | }; |
| 461 | 470 | ||
| 462 | struct dcn10_link_encoder { | 471 | struct dcn10_link_encoder { |
| @@ -403,6 +403,7 @@ static const struct opp_funcs dcn10_opp_funcs = { · 402 unmodified lines | |||
| 403 | .opp_program_stereo = opp1_program_stereo, | 403 | .opp_program_stereo = opp1_program_stereo, |
| 404 | .opp_pipe_clock_control = opp1_pipe_clock_control, | 404 | .opp_pipe_clock_control = opp1_pipe_clock_control, |
| 405 | .opp_set_disp_pattern_generator = NULL, | 405 | .opp_set_disp_pattern_generator = NULL, |
| 406 | .opp_program_dpg_dimensions = NULL, | ||
| 406 | .dpg_is_blanked = NULL, | 407 | .dpg_is_blanked = NULL, |
| 407 | .opp_destroy = opp1_destroy | 408 | .opp_destroy = opp1_destroy |
| 408 | }; | 409 | }; |
| @@ -299,16 +299,13 @@ void optc1_program_timing( · 298 unmodified lines | |||
| 299 | REG_UPDATE(OPTC_DATA_FORMAT_CONTROL, OPTC_DATA_FORMAT, data_fmt); | 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 | if (optc1->tg_mask->OTG_H_TIMING_DIV_MODE != 0) { | 302 | if (optc1->tg_mask->OTG_H_TIMING_DIV_MODE != 0) { |
| 304 | if (optc1->opp_count == 4) | 303 | if (optc1->opp_count == 4) |
| 305 | h_div = H_TIMING_DIV_BY4; | 304 | h_div = H_TIMING_DIV_BY4; |
| 306 | 305 | ||
| 307 | REG_UPDATE(OTG_H_TIMING_CNTL, | 306 | REG_UPDATE(OTG_H_TIMING_CNTL, |
| 308 | OTG_H_TIMING_DIV_MODE, h_div); | 307 | OTG_H_TIMING_DIV_MODE, h_div); |
| 309 | } else | 308 | } else { |
| 310 | #endif | ||
| 311 | { | ||
| 312 | REG_UPDATE(OTG_H_TIMING_CNTL, | 309 | REG_UPDATE(OTG_H_TIMING_CNTL, |
| 313 | OTG_H_TIMING_DIV_BY2, h_div); | 310 | OTG_H_TIMING_DIV_BY2, h_div); |
| 314 | } | 311 | } |
| @@ -171,7 +171,6 @@ struct dcn_optc_registers { · 170 unmodified lines | |||
| 171 | uint32_t OPTC_DATA_FORMAT_CONTROL; | 171 | uint32_t OPTC_DATA_FORMAT_CONTROL; |
| 172 | uint32_t OPTC_BYTES_PER_PIXEL; | 172 | uint32_t OPTC_BYTES_PER_PIXEL; |
| 173 | uint32_t OPTC_WIDTH_CONTROL; | 173 | uint32_t OPTC_WIDTH_CONTROL; |
| 174 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 175 | uint32_t OTG_BLANK_DATA_COLOR; | 174 | uint32_t OTG_BLANK_DATA_COLOR; |
| 176 | uint32_t OTG_BLANK_DATA_COLOR_EXT; | 175 | uint32_t OTG_BLANK_DATA_COLOR_EXT; |
| 177 | uint32_t OTG_DRR_TRIGGER_WINDOW; | 176 | uint32_t OTG_DRR_TRIGGER_WINDOW; |
| @@ -179,7 +178,6 @@ struct dcn_optc_registers { · 1 unmodified line | |||
| 179 | uint32_t OTG_M_CONST_DTO1; | 178 | uint32_t OTG_M_CONST_DTO1; |
| 180 | uint32_t OTG_DRR_V_TOTAL_CHANGE; | 179 | uint32_t OTG_DRR_V_TOTAL_CHANGE; |
| 181 | uint32_t OTG_GLOBAL_CONTROL4; | 180 | uint32_t OTG_GLOBAL_CONTROL4; |
| 182 | #endif | ||
| 183 | }; | 181 | }; |
| 184 | 182 | ||
| 185 | #define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\ | 183 | #define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\ |
| @@ -474,8 +472,6 @@ struct dcn_optc_registers { · 288 unmodified lines | |||
| 474 | type MANUAL_FLOW_CONTROL;\ | 472 | type MANUAL_FLOW_CONTROL;\ |
| 475 | type MANUAL_FLOW_CONTROL_SEL; | 473 | type MANUAL_FLOW_CONTROL_SEL; |
| 476 | 474 | ||
| 477 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 478 | |||
| 479 | #define TG_REG_FIELD_LIST(type) \ | 475 | #define TG_REG_FIELD_LIST(type) \ |
| 480 | TG_REG_FIELD_LIST_DCN1_0(type)\ | 476 | TG_REG_FIELD_LIST_DCN1_0(type)\ |
| 481 | type OTG_V_SYNC_MODE;\ | 477 | type OTG_V_SYNC_MODE;\ |
| @@ -517,33 +513,6 @@ struct dcn_optc_registers { · 35 unmodified lines | |||
| 517 | type OTG_CRC_DATA_STREAM_COMBINE_MODE;\ | 513 | type OTG_CRC_DATA_STREAM_COMBINE_MODE;\ |
| 518 | type OTG_CRC_DATA_STREAM_SPLIT_MODE;\ | 514 | type OTG_CRC_DATA_STREAM_SPLIT_MODE;\ |
| 519 | type OTG_CRC_DATA_FORMAT; | 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 | struct dcn_optc_shift { | 518 | struct dcn_optc_shift { |
| @@ -1416,7 +1416,9 @@ static bool dcn10_resource_construct( · 1415 unmodified lines | |||
| 1416 | dc->caps.max_video_width = 3840; | 1416 | dc->caps.max_video_width = 3840; |
| 1417 | dc->caps.max_downscale_ratio = 200; | 1417 | dc->caps.max_downscale_ratio = 200; |
| 1418 | dc->caps.i2c_speed_in_khz = 100; | 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 | dc->caps.max_cursor_size = 256; | 1420 | dc->caps.max_cursor_size = 256; |
| 1421 | dc->caps.min_horizontal_blanking_period = 80; | ||
| 1420 | dc->caps.max_slave_planes = 1; | 1422 | dc->caps.max_slave_planes = 1; |
| 1421 | dc->caps.is_apu = true; | 1423 | dc->caps.is_apu = true; |
| 1422 | dc->caps.post_blend_color_processing = false; | 1424 | dc->caps.post_blend_color_processing = false; |
| @@ -169,14 +169,12 @@ struct dcn10_stream_enc_registers { · 168 unmodified lines | |||
| 169 | uint32_t DP_SEC_METADATA_TRANSMISSION; | 169 | uint32_t DP_SEC_METADATA_TRANSMISSION; |
| 170 | uint32_t HDMI_METADATA_PACKET_CONTROL; | 170 | uint32_t HDMI_METADATA_PACKET_CONTROL; |
| 171 | uint32_t DP_SEC_FRAMING4; | 171 | uint32_t DP_SEC_FRAMING4; |
| 172 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 173 | uint32_t DP_GSP11_CNTL; | 172 | uint32_t DP_GSP11_CNTL; |
| 174 | uint32_t HDMI_GENERIC_PACKET_CONTROL6; | 173 | uint32_t HDMI_GENERIC_PACKET_CONTROL6; |
| 175 | uint32_t HDMI_GENERIC_PACKET_CONTROL7; | 174 | uint32_t HDMI_GENERIC_PACKET_CONTROL7; |
| 176 | uint32_t HDMI_GENERIC_PACKET_CONTROL8; | 175 | uint32_t HDMI_GENERIC_PACKET_CONTROL8; |
| 177 | uint32_t HDMI_GENERIC_PACKET_CONTROL9; | 176 | uint32_t HDMI_GENERIC_PACKET_CONTROL9; |
| 178 | uint32_t HDMI_GENERIC_PACKET_CONTROL10; | 177 | uint32_t HDMI_GENERIC_PACKET_CONTROL10; |
| 179 | #endif | ||
| 180 | uint32_t DIG_CLOCK_PATTERN; | 178 | uint32_t DIG_CLOCK_PATTERN; |
| 181 | }; | 179 | }; |
| 182 | 180 | ||
| @@ -505,7 +503,6 @@ struct dcn10_stream_enc_registers { · 322 unmodified lines | |||
| 505 | type DP_PIXEL_COMBINE;\ | 503 | type DP_PIXEL_COMBINE;\ |
| 506 | type DP_SST_SDP_SPLITTING | 504 | type DP_SST_SDP_SPLITTING |
| 507 | 505 | ||
| 508 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 509 | #define SE_REG_FIELD_LIST_DCN3_0(type) \ | 506 | #define SE_REG_FIELD_LIST_DCN3_0(type) \ |
| 510 | type HDMI_GENERIC8_CONT;\ | 507 | type HDMI_GENERIC8_CONT;\ |
| 511 | type HDMI_GENERIC8_SEND;\ | 508 | type HDMI_GENERIC8_SEND;\ |
| @@ -531,22 +528,17 @@ struct dcn10_stream_enc_registers { · 19 unmodified lines | |||
| 531 | type DP_SEC_GSP11_PPS;\ | 528 | type DP_SEC_GSP11_PPS;\ |
| 532 | type DP_SEC_GSP11_ENABLE;\ | 529 | type DP_SEC_GSP11_ENABLE;\ |
| 533 | type DP_SEC_GSP11_LINE_NUM | 530 | type DP_SEC_GSP11_LINE_NUM |
| 534 | #endif | ||
| 535 | 531 | ||
| 536 | struct dcn10_stream_encoder_shift { | 532 | struct dcn10_stream_encoder_shift { |
| 537 | SE_REG_FIELD_LIST_DCN1_0(uint8_t); | 533 | SE_REG_FIELD_LIST_DCN1_0(uint8_t); |
| 538 | SE_REG_FIELD_LIST_DCN2_0(uint8_t); | 534 | SE_REG_FIELD_LIST_DCN2_0(uint8_t); |
| 539 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 540 | SE_REG_FIELD_LIST_DCN3_0(uint8_t); | 535 | SE_REG_FIELD_LIST_DCN3_0(uint8_t); |
| 541 | #endif | ||
| 542 | }; | 536 | }; |
| 543 | 537 | ||
| 544 | struct dcn10_stream_encoder_mask { | 538 | struct dcn10_stream_encoder_mask { |
| 545 | SE_REG_FIELD_LIST_DCN1_0(uint32_t); | 539 | SE_REG_FIELD_LIST_DCN1_0(uint32_t); |
| 546 | SE_REG_FIELD_LIST_DCN2_0(uint32_t); | 540 | SE_REG_FIELD_LIST_DCN2_0(uint32_t); |
| 547 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 548 | SE_REG_FIELD_LIST_DCN3_0(uint32_t); | 541 | SE_REG_FIELD_LIST_DCN3_0(uint32_t); |
| 549 | #endif | ||
| 550 | }; | 542 | }; |
| 551 | 543 | ||
| 552 | struct dcn10_stream_encoder { | 544 | struct dcn10_stream_encoder { |
| @@ -76,7 +76,6 @@ · 75 unmodified lines | |||
| 76 | type REFCLK_CLOCK_EN;\ | 76 | type REFCLK_CLOCK_EN;\ |
| 77 | type REFCLK_SRC_SEL; | 77 | type REFCLK_SRC_SEL; |
| 78 | 78 | ||
| 79 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 80 | #define DCCG3_REG_FIELD_LIST(type) \ | 79 | #define DCCG3_REG_FIELD_LIST(type) \ |
| 81 | type PHYASYMCLK_FORCE_EN;\ | 80 | type PHYASYMCLK_FORCE_EN;\ |
| 82 | type PHYASYMCLK_FORCE_SRC_SEL;\ | 81 | type PHYASYMCLK_FORCE_SRC_SEL;\ |
| @@ -84,32 +83,25 @@ · 1 unmodified line | |||
| 84 | type PHYBSYMCLK_FORCE_SRC_SEL;\ | 83 | type PHYBSYMCLK_FORCE_SRC_SEL;\ |
| 85 | type PHYCSYMCLK_FORCE_EN;\ | 84 | type PHYCSYMCLK_FORCE_EN;\ |
| 86 | type PHYCSYMCLK_FORCE_SRC_SEL; | 85 | type PHYCSYMCLK_FORCE_SRC_SEL; |
| 87 | #endif | ||
| 88 | 86 | ||
| 89 | struct dccg_shift { | 87 | struct dccg_shift { |
| 90 | DCCG_REG_FIELD_LIST(uint8_t) | 88 | DCCG_REG_FIELD_LIST(uint8_t) |
| 91 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 92 | DCCG3_REG_FIELD_LIST(uint8_t) | 89 | DCCG3_REG_FIELD_LIST(uint8_t) |
| 93 | #endif | ||
| 94 | }; | 90 | }; |
| 95 | 91 | ||
| 96 | struct dccg_mask { | 92 | struct dccg_mask { |
| 97 | DCCG_REG_FIELD_LIST(uint32_t) | 93 | DCCG_REG_FIELD_LIST(uint32_t) |
| 98 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 99 | DCCG3_REG_FIELD_LIST(uint32_t) | 94 | DCCG3_REG_FIELD_LIST(uint32_t) |
| 100 | #endif | ||
| 101 | }; | 95 | }; |
| 102 | 96 | ||
| 103 | struct dccg_registers { | 97 | struct dccg_registers { |
| 104 | uint32_t DPPCLK_DTO_CTRL; | 98 | uint32_t DPPCLK_DTO_CTRL; |
| 105 | uint32_t DPPCLK_DTO_PARAM[6]; | 99 | uint32_t DPPCLK_DTO_PARAM[6]; |
| 106 | uint32_t REFCLK_CNTL; | 100 | uint32_t REFCLK_CNTL; |
| 107 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 108 | uint32_t HDMICHARCLK_CLOCK_CNTL[6]; | 101 | uint32_t HDMICHARCLK_CLOCK_CNTL[6]; |
| 109 | uint32_t PHYASYMCLK_CLOCK_CNTL; | 102 | uint32_t PHYASYMCLK_CLOCK_CNTL; |
| 110 | uint32_t PHYBSYMCLK_CLOCK_CNTL; | 103 | uint32_t PHYBSYMCLK_CLOCK_CNTL; |
| 111 | uint32_t PHYCSYMCLK_CLOCK_CNTL; | 104 | uint32_t PHYCSYMCLK_CLOCK_CNTL; |
| 112 | #endif | ||
| 113 | }; | 105 | }; |
| 114 | 106 | ||
| 115 | struct dcn_dccg { | 107 | struct dcn_dccg { |
| @@ -153,10 +153,8 @@ bool hubbub2_dcc_support_pixel_format( · 152 unmodified lines | |||
| 153 | case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX: | 153 | case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX: |
| 154 | case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT: | 154 | case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT: |
| 155 | case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT: | 155 | case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT: |
| 156 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 157 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE: | 156 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE: |
| 158 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA: | 157 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA: |
| 159 | #endif | ||
| 160 | *bytes_per_element = 4; | 158 | *bytes_per_element = 4; |
| 161 | return true; | 159 | return true; |
| 162 | case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: | 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 | case 65536: | 341 | case 65536: |
| 344 | block_size = DCN_PAGE_TABLE_BLOCK_SIZE_64KB; | 342 | block_size = DCN_PAGE_TABLE_BLOCK_SIZE_64KB; |
| 345 | break; | 343 | break; |
| 346 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 347 | case 32768: | 344 | case 32768: |
| 348 | block_size = DCN_PAGE_TABLE_BLOCK_SIZE_32KB; | 345 | block_size = DCN_PAGE_TABLE_BLOCK_SIZE_32KB; |
| 349 | break; | 346 | break; |
| 350 | #endif | ||
| 351 | default: | 347 | default: |
| 352 | ASSERT(false); | 348 | ASSERT(false); |
| 353 | block_size = page_table_block_size; | 349 | block_size = page_table_block_size; |
| @@ -336,10 +336,8 @@ void hubp2_program_size( · 335 unmodified lines | |||
| 336 | */ | 336 | */ |
| 337 | use_pitch_c = format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN | 337 | use_pitch_c = format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN |
| 338 | && format < SURFACE_PIXEL_FORMAT_SUBSAMPLE_END; | 338 | && format < SURFACE_PIXEL_FORMAT_SUBSAMPLE_END; |
| 339 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 340 | use_pitch_c = use_pitch_c | 339 | use_pitch_c = use_pitch_c |
| 341 | || (format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA); | 340 | || (format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA); |
| 342 | #endif | ||
| 343 | if (use_pitch_c) { | 341 | if (use_pitch_c) { |
| 344 | ASSERT(plane_size->chroma_pitch != 0); | 342 | ASSERT(plane_size->chroma_pitch != 0); |
| 345 | /* Chroma pitch zero can cause system hang! */ | 343 | /* Chroma pitch zero can cause system hang! */ |
| @@ -364,10 +362,8 @@ void hubp2_program_size( · 18 unmodified lines | |||
| 364 | PITCH, pitch, META_PITCH, meta_pitch); | 362 | PITCH, pitch, META_PITCH, meta_pitch); |
| 365 | 363 | ||
| 366 | use_pitch_c = format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN; | 364 | use_pitch_c = format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN; |
| 367 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 368 | use_pitch_c = use_pitch_c | 365 | use_pitch_c = use_pitch_c |
| 369 | || (format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA); | 366 | || (format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA); |
| 370 | #endif | ||
| 371 | if (use_pitch_c) | 367 | if (use_pitch_c) |
| 372 | REG_UPDATE_2(DCSURF_SURFACE_PITCH_C, | 368 | REG_UPDATE_2(DCSURF_SURFACE_PITCH_C, |
| 373 | PITCH_C, pitch_c, META_PITCH_C, meta_pitch_c); | 369 | PITCH_C, pitch_c, META_PITCH_C, meta_pitch_c); |
| @@ -513,7 +509,6 @@ void hubp2_program_pixel_format( · 139 unmodified lines | |||
| 513 | REG_UPDATE(DCSURF_SURFACE_CONFIG, | 509 | REG_UPDATE(DCSURF_SURFACE_CONFIG, |
| 514 | SURFACE_PIXEL_FORMAT, 119); | 510 | SURFACE_PIXEL_FORMAT, 119); |
| 515 | break; | 511 | break; |
| 516 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 517 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE: | 512 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE: |
| 518 | REG_UPDATE_2(DCSURF_SURFACE_CONFIG, | 513 | REG_UPDATE_2(DCSURF_SURFACE_CONFIG, |
| 519 | SURFACE_PIXEL_FORMAT, 116, | 514 | SURFACE_PIXEL_FORMAT, 116, |
| @@ -524,7 +519,6 @@ void hubp2_program_pixel_format( · 4 unmodified lines | |||
| 524 | SURFACE_PIXEL_FORMAT, 116, | 519 | SURFACE_PIXEL_FORMAT, 116, |
| 525 | ALPHA_PLANE_EN, 1); | 520 | ALPHA_PLANE_EN, 1); |
| 526 | break; | 521 | break; |
| 527 | #endif | ||
| 528 | default: | 522 | default: |
| 529 | BREAK_TO_DEBUGGER(); | 523 | BREAK_TO_DEBUGGER(); |
| 530 | break; | 524 | break; |
| @@ -157,11 +157,9 @@ · 156 unmodified lines | |||
| 157 | uint32_t VBLANK_PARAMETERS_5;\ | 157 | uint32_t VBLANK_PARAMETERS_5;\ |
| 158 | uint32_t VBLANK_PARAMETERS_6 | 158 | uint32_t VBLANK_PARAMETERS_6 |
| 159 | 159 | ||
| 160 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 161 | #define DCN30_HUBP_REG_COMMON_VARIABLE_LIST \ | 160 | #define DCN30_HUBP_REG_COMMON_VARIABLE_LIST \ |
| 162 | DCN21_HUBP_REG_COMMON_VARIABLE_LIST;\ | 161 | DCN21_HUBP_REG_COMMON_VARIABLE_LIST;\ |
| 163 | uint32_t DCN_DMDATA_VM_CNTL | 162 | uint32_t DCN_DMDATA_VM_CNTL |
| 164 | #endif | ||
| 165 | 163 | ||
| 166 | #define DCN2_HUBP_REG_FIELD_VARIABLE_LIST(type) \ | 164 | #define DCN2_HUBP_REG_FIELD_VARIABLE_LIST(type) \ |
| 167 | DCN_HUBP_REG_FIELD_BASE_LIST(type); \ | 165 | DCN_HUBP_REG_FIELD_BASE_LIST(type); \ |
| @@ -198,7 +196,6 @@ · 30 unmodified lines | |||
| 198 | type REFCYC_PER_META_CHUNK_FLIP_C; \ | 196 | type REFCYC_PER_META_CHUNK_FLIP_C; \ |
| 199 | type VM_GROUP_SIZE | 197 | type VM_GROUP_SIZE |
| 200 | 198 | ||
| 201 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 202 | #define DCN30_HUBP_REG_FIELD_VARIABLE_LIST(type) \ | 199 | #define DCN30_HUBP_REG_FIELD_VARIABLE_LIST(type) \ |
| 203 | DCN21_HUBP_REG_FIELD_VARIABLE_LIST(type);\ | 200 | DCN21_HUBP_REG_FIELD_VARIABLE_LIST(type);\ |
| 204 | type PRIMARY_SURFACE_DCC_IND_BLK;\ | 201 | type PRIMARY_SURFACE_DCC_IND_BLK;\ |
| @@ -218,32 +215,17 @@ · 13 unmodified lines | |||
| 218 | type PACK_3TO2_ELEMENT_DISABLE; \ | 215 | type PACK_3TO2_ELEMENT_DISABLE; \ |
| 219 | type ROW_TTU_MODE; \ | 216 | type ROW_TTU_MODE; \ |
| 220 | type NUM_PKRS | 217 | type NUM_PKRS |
| 221 | #endif | ||
| 222 | 218 | ||
| 223 | struct dcn_hubp2_registers { | 219 | struct dcn_hubp2_registers { |
| 224 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 225 | DCN30_HUBP_REG_COMMON_VARIABLE_LIST; | 220 | DCN30_HUBP_REG_COMMON_VARIABLE_LIST; |
| 226 | #else | ||
| 227 | DCN21_HUBP_REG_COMMON_VARIABLE_LIST; | ||
| 228 | #endif | ||
| 229 | }; | 221 | }; |
| 230 | 222 | ||
| 231 | struct dcn_hubp2_shift { | 223 | struct dcn_hubp2_shift { |
| 232 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 233 | DCN30_HUBP_REG_FIELD_VARIABLE_LIST(uint8_t); | 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 | struct dcn_hubp2_mask { | 227 | struct dcn_hubp2_mask { |
| 241 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 242 | DCN30_HUBP_REG_FIELD_VARIABLE_LIST(uint32_t); | 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 | struct dcn20_hubp { | 231 | struct dcn20_hubp { |
| @@ -611,7 +611,6 @@ void dcn20_disable_plane(struct dc *dc, struct pipe_ctx *pipe_ctx) · 610 unmodified lines | |||
| 611 | pipe_ctx->pipe_idx); | 611 | pipe_ctx->pipe_idx); |
| 612 | } | 612 | } |
| 613 | 613 | ||
| 614 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 615 | static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream, | 614 | static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream, |
| 616 | int opp_cnt) | 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 | return flow_ctrl_cnt; | 634 | return flow_ctrl_cnt; |
| 636 | } | 635 | } |
| 637 | #endif | ||
| 638 | 636 | ||
| 639 | enum dc_status dcn20_enable_stream_timing( | 637 | enum dc_status dcn20_enable_stream_timing( |
| 640 | struct pipe_ctx *pipe_ctx, | 638 | struct pipe_ctx *pipe_ctx, |
| @@ -648,16 +646,12 @@ enum dc_status dcn20_enable_stream_timing( · 7 unmodified lines | |||
| 648 | struct pipe_ctx *odm_pipe; | 646 | struct pipe_ctx *odm_pipe; |
| 649 | int opp_cnt = 1; | 647 | int opp_cnt = 1; |
| 650 | int opp_inst[MAX_PIPES] = { pipe_ctx->stream_res.opp->inst }; | 648 | int opp_inst[MAX_PIPES] = { pipe_ctx->stream_res.opp->inst }; |
| 651 | |||
| 652 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 653 | bool interlace = stream->timing.flags.INTERLACE; | 649 | bool interlace = stream->timing.flags.INTERLACE; |
| 654 | int i; | 650 | int i; |
| 655 | |||
| 656 | struct mpc_dwb_flow_control flow_control; | 651 | struct mpc_dwb_flow_control flow_control; |
| 657 | struct mpc *mpc = dc->res_pool->mpc; | 652 | struct mpc *mpc = dc->res_pool->mpc; |
| 658 | bool rate_control_2x_pclk = (interlace || optc2_is_two_pixels_per_containter(&stream->timing)); | 653 | bool rate_control_2x_pclk = (interlace || optc2_is_two_pixels_per_containter(&stream->timing)); |
| 659 | 654 | ||
| 660 | #endif | ||
| 661 | /* by upper caller loop, pipe0 is parent pipe and be called first. | 655 | /* by upper caller loop, pipe0 is parent pipe and be called first. |
| 662 | * back end is set up by for pipe0. Other children pipe share back end | 656 | * back end is set up by for pipe0. Other children pipe share back end |
| 663 | * with pipe 0. No program is needed. | 657 | * with pipe 0. No program is needed. |
| @@ -704,7 +698,6 @@ enum dc_status dcn20_enable_stream_timing( · 40 unmodified lines | |||
| 704 | pipe_ctx->stream->signal, | 698 | pipe_ctx->stream->signal, |
| 705 | true); | 699 | true); |
| 706 | 700 | ||
| 707 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 708 | rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1; | 701 | rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1; |
| 709 | flow_control.flow_ctrl_mode = 0; | 702 | flow_control.flow_ctrl_mode = 0; |
| 710 | flow_control.flow_ctrl_cnt0 = 0x80; | 703 | flow_control.flow_ctrl_cnt0 = 0x80; |
| @@ -718,7 +711,7 @@ enum dc_status dcn20_enable_stream_timing( · 7 unmodified lines | |||
| 718 | &flow_control); | 711 | &flow_control); |
| 719 | } | 712 | } |
| 720 | } | 713 | } |
| 721 | #endif | 714 | |
| 722 | for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) | 715 | for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) |
| 723 | odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control( | 716 | odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control( |
| 724 | odm_pipe->stream_res.opp, | 717 | odm_pipe->stream_res.opp, |
| @@ -1030,8 +1023,8 @@ void dcn20_blank_pixel_data( · 305 unmodified lines | |||
| 1030 | test_pattern = CONTROLLER_DP_TEST_PATTERN_VIDEOMODE; | 1023 | test_pattern = CONTROLLER_DP_TEST_PATTERN_VIDEOMODE; |
| 1031 | } | 1024 | } |
| 1032 | 1025 | ||
| 1033 | stream_res->opp->funcs->opp_set_disp_pattern_generator( | 1026 | dc->hwss.set_disp_pattern_generator(dc, |
| 1034 | stream_res->opp, | 1027 | pipe_ctx, |
| 1035 | test_pattern, | 1028 | test_pattern, |
| 1036 | test_pattern_color_space, | 1029 | test_pattern_color_space, |
| 1037 | stream->timing.display_color_depth, | 1030 | stream->timing.display_color_depth, |
| @@ -1041,8 +1034,8 @@ void dcn20_blank_pixel_data( · 3 unmodified lines | |||
| 1041 | 0); | 1034 | 0); |
| 1042 | 1035 | ||
| 1043 | for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) { | 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( | 1037 | dc->hwss.set_disp_pattern_generator(dc, |
| 1045 | odm_pipe->stream_res.opp, | 1038 | odm_pipe, |
| 1046 | dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE && blank ? | 1039 | dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE && blank ? |
| 1047 | CONTROLLER_DP_TEST_PATTERN_COLORRAMP : test_pattern, | 1040 | CONTROLLER_DP_TEST_PATTERN_COLORRAMP : test_pattern, |
| 1048 | test_pattern_color_space, | 1041 | test_pattern_color_space, |
| @@ -1158,6 +1151,7 @@ void dcn20_pipe_control_lock( · 109 unmodified lines | |||
| 1158 | struct pipe_ctx *pipe, | 1151 | struct pipe_ctx *pipe, |
| 1159 | bool lock) | 1152 | bool lock) |
| 1160 | { | 1153 | { |
| 1154 | struct pipe_ctx *temp_pipe; | ||
| 1161 | bool flip_immediate = false; | 1155 | bool flip_immediate = false; |
| 1162 | 1156 | ||
| 1163 | /* use TG master update lock to lock everything on the TG | 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 | if (pipe->plane_state != NULL) | 1163 | if (pipe->plane_state != NULL) |
| 1170 | flip_immediate = pipe->plane_state->flip_immediate; | 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 | if (flip_immediate && lock) { | 1173 | if (flip_immediate && lock) { |
| 1173 | const int TIMEOUT_FOR_FLIP_PENDING = 100000; | 1174 | const int TIMEOUT_FOR_FLIP_PENDING = 100000; |
| 1174 | int i; | 1175 | int i; |
| @@ -1191,11 +1192,25 @@ void dcn20_pipe_control_lock( · 16 unmodified lines | |||
| 1191 | /* In flip immediate and pipe splitting case, we need to use GSL | 1192 | /* In flip immediate and pipe splitting case, we need to use GSL |
| 1192 | * for synchronization. Only do setup on locking and on flip type change. | 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 | if ((flip_immediate && pipe->stream_res.gsl_group == 0) || | 1196 | if ((flip_immediate && pipe->stream_res.gsl_group == 0) || |
| 1196 | (!flip_immediate && pipe->stream_res.gsl_group > 0)) | 1197 | (!flip_immediate && pipe->stream_res.gsl_group > 0)) |
| 1197 | dcn20_setup_gsl_group_as_lock(dc, pipe, flip_immediate); | 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 | if (pipe->stream && should_use_dmub_lock(pipe->stream->link)) { | 1214 | if (pipe->stream && should_use_dmub_lock(pipe->stream->link)) { |
| 1200 | union dmub_hw_lock_flags hw_locks = { 0 }; | 1215 | union dmub_hw_lock_flags hw_locks = { 0 }; |
| 1201 | struct dmub_hw_lock_inst_flags inst_flags = { 0 }; | 1216 | struct dmub_hw_lock_inst_flags inst_flags = { 0 }; |
| @@ -1478,7 +1493,6 @@ static void dcn20_update_dchubp_dpp( · 276 unmodified lines | |||
| 1478 | if (pipe_ctx->update_flags.bits.enable || pipe_ctx->update_flags.bits.opp_changed | 1493 | if (pipe_ctx->update_flags.bits.enable || pipe_ctx->update_flags.bits.opp_changed |
| 1479 | || pipe_ctx->stream->update_flags.bits.gamut_remap | 1494 | || pipe_ctx->stream->update_flags.bits.gamut_remap |
| 1480 | || pipe_ctx->stream->update_flags.bits.out_csc) { | 1495 | || pipe_ctx->stream->update_flags.bits.out_csc) { |
| 1481 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 1482 | struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc; | 1496 | struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc; |
| 1483 | 1497 | ||
| 1484 | if (mpc->funcs->set_gamut_remap) { | 1498 | if (mpc->funcs->set_gamut_remap) { |
| @@ -1509,7 +1523,6 @@ static void dcn20_update_dchubp_dpp( · 24 unmodified lines | |||
| 1509 | } | 1523 | } |
| 1510 | mpc->funcs->set_gamut_remap(mpc, mpcc_id, &adjust); | 1524 | mpc->funcs->set_gamut_remap(mpc, mpcc_id, &adjust); |
| 1511 | } else | 1525 | } else |
| 1512 | #endif | ||
| 1513 | /* dpp/cm gamut remap*/ | 1526 | /* dpp/cm gamut remap*/ |
| 1514 | dc->hwss.program_gamut_remap(pipe_ctx); | 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 | plane_state->address.type = PLN_ADDR_TYPE_GRPH_STEREO; | 2047 | plane_state->address.type = PLN_ADDR_TYPE_GRPH_STEREO; |
| 2035 | plane_state->address.grph_stereo.right_addr = | 2048 | plane_state->address.grph_stereo.right_addr = |
| 2036 | plane_state->address.grph_stereo.left_addr; | 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 | return false; | 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 | blnd_cfg.bottom_inside_gain = 0x1f000; | 2297 | blnd_cfg.bottom_inside_gain = 0x1f000; |
| 2283 | blnd_cfg.bottom_outside_gain = 0x1f000; | 2298 | blnd_cfg.bottom_outside_gain = 0x1f000; |
| 2284 | blnd_cfg.pre_multiplied_alpha = per_pixel_alpha; | 2299 | blnd_cfg.pre_multiplied_alpha = per_pixel_alpha; |
| 2285 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 2286 | if (pipe_ctx->plane_state->format | 2300 | if (pipe_ctx->plane_state->format |
| 2287 | == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA) | 2301 | == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA) |
| 2288 | blnd_cfg.pre_multiplied_alpha = false; | 2302 | blnd_cfg.pre_multiplied_alpha = false; |
| 2289 | #endif | ||
| 2290 | 2303 | ||
| 2291 | /* | 2304 | /* |
| 2292 | * TODO: remove hack | 2305 | * TODO: remove hack |
| @@ -2545,3 +2558,15 @@ bool dcn20_optimize_timing_for_fsft(struct dc *dc, · 252 unmodified lines | |||
| 2545 | return true; | 2558 | return true; |
| 2546 | } | 2559 | } |
| 2547 | #endif | 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 | struct dc_crtc_timing *timing, | 137 | struct dc_crtc_timing *timing, |
| 138 | unsigned int max_input_rate_in_khz); | 138 | unsigned int max_input_rate_in_khz); |
| 139 | #endif | 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 | #endif /* __DC_HWSS_DCN20_H__ */ | 149 | #endif /* __DC_HWSS_DCN20_H__ */ |
| 141 | 150 | ||
| @@ -34,7 +34,6 @@ static const struct hw_sequencer_funcs dcn20_funcs = { · 33 unmodified lines | |||
| 34 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, | 34 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, |
| 35 | .apply_ctx_for_surface = NULL, | 35 | .apply_ctx_for_surface = NULL, |
| 36 | .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, | 36 | .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, |
| 37 | .disconnect_pipes = dcn10_disconnect_pipes, | ||
| 38 | .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, | 37 | .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, |
| 39 | .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, | 38 | .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, |
| 40 | .update_plane_addr = dcn20_update_plane_addr, | 39 | .update_plane_addr = dcn20_update_plane_addr, |
| @@ -94,6 +93,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { · 53 unmodified lines | |||
| 94 | #ifndef TRIM_FSFT | 93 | #ifndef TRIM_FSFT |
| 95 | .optimize_timing_for_fsft = dcn20_optimize_timing_for_fsft, | 94 | .optimize_timing_for_fsft = dcn20_optimize_timing_for_fsft, |
| 96 | #endif | 95 | #endif |
| 96 | .set_disp_pattern_generator = dcn20_set_disp_pattern_generator, | ||
| 97 | }; | 97 | }; |
| 98 | 98 | ||
| 99 | static const struct hwseq_private_funcs dcn20_private_funcs = { | 99 | static const struct hwseq_private_funcs dcn20_private_funcs = { |
| @@ -276,10 +276,8 @@ struct mpll_cfg { · 275 unmodified lines | |||
| 276 | bool dp_tx1_vergdrv_byp; | 276 | bool dp_tx1_vergdrv_byp; |
| 277 | bool dp_tx2_vergdrv_byp; | 277 | bool dp_tx2_vergdrv_byp; |
| 278 | bool dp_tx3_vergdrv_byp; | 278 | bool dp_tx3_vergdrv_byp; |
| 279 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 280 | uint32_t tx_peaking_lvl; | 279 | uint32_t tx_peaking_lvl; |
| 281 | uint32_t ctr_reqs_pll; | 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 | void opp2_dpg_set_blank_color( | 304 | void opp2_dpg_set_blank_color( |
| 294 | struct output_pixel_processor *opp, | 305 | struct output_pixel_processor *opp, |
| 295 | const struct tg_color *color) | 306 | const struct tg_color *color) |
| @@ -350,6 +361,7 @@ static struct opp_funcs dcn20_opp_funcs = { · 54 unmodified lines | |||
| 350 | .opp_program_stereo = opp1_program_stereo, | 361 | .opp_program_stereo = opp1_program_stereo, |
| 351 | .opp_pipe_clock_control = opp1_pipe_clock_control, | 362 | .opp_pipe_clock_control = opp1_pipe_clock_control, |
| 352 | .opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator, | 363 | .opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator, |
| 364 | .opp_program_dpg_dimensions = opp2_program_dpg_dimensions, | ||
| 353 | .dpg_is_blanked = opp2_dpg_is_blanked, | 365 | .dpg_is_blanked = opp2_dpg_is_blanked, |
| 354 | .opp_dpg_set_blank_color = opp2_dpg_set_blank_color, | 366 | .opp_dpg_set_blank_color = opp2_dpg_set_blank_color, |
| 355 | .opp_destroy = opp1_destroy, | 367 | .opp_destroy = opp1_destroy, |
| @@ -153,6 +153,10 @@ void opp2_set_disp_pattern_generator( · 152 unmodified lines | |||
| 153 | int height, | 153 | int height, |
| 154 | int offset); | 154 | int offset); |
| 155 | 155 | ||
| 156 | void opp2_program_dpg_dimensions( | ||
| 157 | struct output_pixel_processor *opp, | ||
| 158 | int width, int height); | ||
| 159 | |||
| 156 | bool opp2_dpg_is_blanked(struct output_pixel_processor *opp); | 160 | bool opp2_dpg_is_blanked(struct output_pixel_processor *opp); |
| 157 | 161 | ||
| 158 | void opp2_dpg_set_blank_color( | 162 | void opp2_dpg_set_blank_color( |
| @@ -1882,9 +1882,16 @@ bool dcn20_split_stream_for_odm( · 1881 unmodified lines | |||
| 1882 | next_odm_pipe->next_odm_pipe = prev_odm_pipe->next_odm_pipe; | 1882 | next_odm_pipe->next_odm_pipe = prev_odm_pipe->next_odm_pipe; |
| 1883 | next_odm_pipe->next_odm_pipe->prev_odm_pipe = next_odm_pipe; | 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 | prev_odm_pipe->next_odm_pipe = next_odm_pipe; | 1893 | prev_odm_pipe->next_odm_pipe = next_odm_pipe; |
| 1886 | next_odm_pipe->prev_odm_pipe = prev_odm_pipe; | 1894 | next_odm_pipe->prev_odm_pipe = prev_odm_pipe; |
| 1887 | ASSERT(next_odm_pipe->top_pipe == NULL); | ||
| 1888 | 1895 | ||
| 1889 | if (prev_odm_pipe->plane_state) { | 1896 | if (prev_odm_pipe->plane_state) { |
| 1890 | struct scaler_data *sd = &prev_odm_pipe->plane_res.scl_data; | 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 | sd->ratios.horz_c, sd->h_active - sd->recout.x)); | 1929 | sd->ratios.horz_c, sd->h_active - sd->recout.x)); |
| 1923 | sd->recout.x = 0; | 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 | if (next_odm_pipe->stream->timing.flags.DSC == 1) { | 1936 | if (next_odm_pipe->stream->timing.flags.DSC == 1) { |
| 1927 | dcn20_acquire_dsc(dc, res_ctx, &next_odm_pipe->stream_res.dsc, next_odm_pipe->pipe_idx); | 1937 | dcn20_acquire_dsc(dc, res_ctx, &next_odm_pipe->stream_res.dsc, next_odm_pipe->pipe_idx); |
| 1928 | ASSERT(next_odm_pipe->stream_res.dsc); | 1938 | ASSERT(next_odm_pipe->stream_res.dsc); |
| @@ -2033,10 +2043,8 @@ int dcn20_populate_dml_pipes_from_context( · 104 unmodified lines | |||
| 2033 | unsigned int v_total; | 2043 | unsigned int v_total; |
| 2034 | unsigned int front_porch; | 2044 | unsigned int front_porch; |
| 2035 | int output_bpc; | 2045 | int output_bpc; |
| 2036 | |||
| 2037 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 2038 | struct audio_check aud_check = {0}; | 2046 | struct audio_check aud_check = {0}; |
| 2039 | #endif | 2047 | |
| 2040 | if (!res_ctx->pipe_ctx[i].stream) | 2048 | if (!res_ctx->pipe_ctx[i].stream) |
| 2041 | continue; | 2049 | continue; |
| 2042 | 2050 | ||
| @@ -2091,11 +2099,9 @@ int dcn20_populate_dml_pipes_from_context( · 48 unmodified lines | |||
| 2091 | case 1: | 2099 | case 1: |
| 2092 | pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_2to1; | 2100 | pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_2to1; |
| 2093 | break; | 2101 | break; |
| 2094 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 2095 | case 3: | 2102 | case 3: |
| 2096 | pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_4to1; | 2103 | pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_4to1; |
| 2097 | break; | 2104 | break; |
| 2098 | #endif | ||
| 2099 | default: | 2105 | default: |
| 2100 | pipes[pipe_cnt].pipe.dest.odm_combine = dm_odm_combine_mode_disabled; | 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 | /* todo: default max for now, until there is logic reflecting this in dc*/ | 2208 | /* todo: default max for now, until there is logic reflecting this in dc*/ |
| 2203 | pipes[pipe_cnt].dout.output_bpc = 12; | 2209 | pipes[pipe_cnt].dout.output_bpc = 12; |
| 2204 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 2205 | /*fill up the audio sample rate (unit in kHz)*/ | 2210 | /*fill up the audio sample rate (unit in kHz)*/ |
| 2206 | get_audio_check(&res_ctx->pipe_ctx[i].stream->audio_info, &aud_check); | 2211 | get_audio_check(&res_ctx->pipe_ctx[i].stream->audio_info, &aud_check); |
| 2207 | pipes[pipe_cnt].dout.max_audio_sample_rate = aud_check.max_audiosample_rate / 1000; | 2212 | pipes[pipe_cnt].dout.max_audio_sample_rate = aud_check.max_audiosample_rate / 1000; |
| 2208 | #endif | ||
| 2209 | /* | 2213 | /* |
| 2210 | * For graphic plane, cursor number is 1, nv12 is 0 | 2214 | * For graphic plane, cursor number is 1, nv12 is 0 |
| 2211 | * bw calculations due to cursor on/off | 2215 | * bw calculations due to cursor on/off |
| @@ -2252,13 +2256,10 @@ int dcn20_populate_dml_pipes_from_context( · 40 unmodified lines | |||
| 2252 | if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_2to1) { | 2256 | if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_2to1) { |
| 2253 | pipes[pipe_cnt].pipe.src.viewport_width /= 2; | 2257 | pipes[pipe_cnt].pipe.src.viewport_width /= 2; |
| 2254 | pipes[pipe_cnt].pipe.dest.recout_width /= 2; | 2258 | pipes[pipe_cnt].pipe.dest.recout_width /= 2; |
| 2255 | } | 2259 | } else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1) { |
| 2256 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 2257 | else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1) { | ||
| 2258 | pipes[pipe_cnt].pipe.src.viewport_width /= 4; | 2260 | pipes[pipe_cnt].pipe.src.viewport_width /= 4; |
| 2259 | pipes[pipe_cnt].pipe.dest.recout_width /= 4; | 2261 | pipes[pipe_cnt].pipe.dest.recout_width /= 4; |
| 2260 | } | 2262 | } |
| 2261 | #endif | ||
| 2262 | } else { | 2263 | } else { |
| 2263 | struct dc_plane_state *pln = res_ctx->pipe_ctx[i].plane_state; | 2264 | struct dc_plane_state *pln = res_ctx->pipe_ctx[i].plane_state; |
| 2264 | struct scaler_data *scl = &res_ctx->pipe_ctx[i].plane_res.scl_data; | 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 | pipes[pipe_cnt].pipe.src.surface_height_y = pln->plane_size.surface_size.height; | 2288 | pipes[pipe_cnt].pipe.src.surface_height_y = pln->plane_size.surface_size.height; |
| 2288 | pipes[pipe_cnt].pipe.src.surface_width_c = pln->plane_size.chroma_size.width; | 2289 | pipes[pipe_cnt].pipe.src.surface_width_c = pln->plane_size.chroma_size.width; |
| 2289 | pipes[pipe_cnt].pipe.src.surface_height_c = pln->plane_size.chroma_size.height; | 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 | if (pln->format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA | 2291 | if (pln->format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA |
| 2292 | || pln->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { | 2292 | || pln->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { |
| 2293 | #else | ||
| 2294 | if (pln->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { | ||
| 2295 | #endif | ||
| 2296 | pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch; | 2293 | pipes[pipe_cnt].pipe.src.data_pitch = pln->plane_size.surface_pitch; |
| 2297 | pipes[pipe_cnt].pipe.src.data_pitch_c = pln->plane_size.chroma_pitch; | 2294 | pipes[pipe_cnt].pipe.src.data_pitch_c = pln->plane_size.chroma_pitch; |
| 2298 | pipes[pipe_cnt].pipe.src.meta_pitch = pln->dcc.meta_pitch; | 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 | pipes[pipe_cnt].pipe.dest.full_recout_width = scl->recout.width; | 2305 | pipes[pipe_cnt].pipe.dest.full_recout_width = scl->recout.width; |
| 2309 | if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_2to1) | 2306 | if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_2to1) |
| 2310 | pipes[pipe_cnt].pipe.dest.full_recout_width *= 2; | 2307 | pipes[pipe_cnt].pipe.dest.full_recout_width *= 2; |
| 2311 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 2312 | else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1) | 2308 | else if (pipes[pipe_cnt].pipe.dest.odm_combine == dm_odm_combine_mode_4to1) |
| 2313 | pipes[pipe_cnt].pipe.dest.full_recout_width *= 4; | 2309 | pipes[pipe_cnt].pipe.dest.full_recout_width *= 4; |
| 2314 | #endif | ||
| 2315 | else { | 2310 | else { |
| 2316 | struct pipe_ctx *split_pipe = res_ctx->pipe_ctx[i].bottom_pipe; | 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 | case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS: | 2363 | case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS: |
| 2369 | pipes[pipe_cnt].pipe.src.source_format = dm_444_8; | 2364 | pipes[pipe_cnt].pipe.src.source_format = dm_444_8; |
| 2370 | break; | 2365 | break; |
| 2371 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 2372 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA: | 2366 | case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA: |
| 2373 | pipes[pipe_cnt].pipe.src.source_format = dm_rgbe_alpha; | 2367 | pipes[pipe_cnt].pipe.src.source_format = dm_rgbe_alpha; |
| 2374 | break; | 2368 | break; |
| 2375 | #endif | ||
| 2376 | default: | 2369 | default: |
| 2377 | pipes[pipe_cnt].pipe.src.source_format = dm_444_32; | 2370 | pipes[pipe_cnt].pipe.src.source_format = dm_444_32; |
| 2378 | break; | 2371 | break; |
| @@ -2582,7 +2575,7 @@ struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc, · 203 unmodified lines | |||
| 2582 | return secondary_pipe; | 2575 | return secondary_pipe; |
| 2583 | } | 2576 | } |
| 2584 | 2577 | ||
| 2585 | static void dcn20_merge_pipes_for_validate( | 2578 | void dcn20_merge_pipes_for_validate( |
| 2586 | struct dc *dc, | 2579 | struct dc *dc, |
| 2587 | struct dc_state *context) | 2580 | struct dc_state *context) |
| 2588 | { | 2581 | { |
| @@ -2749,7 +2742,6 @@ int dcn20_validate_apply_pipe_split_flags( · 160 unmodified lines | |||
| 2749 | split[i] = 2; | 2742 | split[i] = 2; |
| 2750 | v->ODMCombineEnablePerState[vlevel][pipe_plane] = dm_odm_combine_mode_2to1; | 2743 | v->ODMCombineEnablePerState[vlevel][pipe_plane] = dm_odm_combine_mode_2to1; |
| 2751 | } | 2744 | } |
| 2752 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 2753 | if (dc->debug.force_odm_combine_4to1 & (1 << pipe->stream_res.tg->inst)) { | 2745 | if (dc->debug.force_odm_combine_4to1 & (1 << pipe->stream_res.tg->inst)) { |
| 2754 | split[i] = 4; | 2746 | split[i] = 4; |
| 2755 | v->ODMCombineEnablePerState[vlevel][pipe_plane] = dm_odm_combine_mode_4to1; | 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 | pipe->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) { | 2751 | pipe->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) { |
| 2760 | split[i] = 4; | 2752 | split[i] = 4; |
| 2761 | } | 2753 | } |
| 2762 | #endif | ||
| 2763 | v->ODMCombineEnabled[pipe_plane] = | 2754 | v->ODMCombineEnabled[pipe_plane] = |
| 2764 | v->ODMCombineEnablePerState[vlevel][pipe_plane]; | 2755 | v->ODMCombineEnablePerState[vlevel][pipe_plane]; |
| 2765 | 2756 | ||
| @@ -3801,7 +3792,9 @@ static bool dcn20_resource_construct( · 1035 unmodified lines | |||
| 3801 | 3792 | ||
| 3802 | dc->caps.max_downscale_ratio = 200; | 3793 | dc->caps.max_downscale_ratio = 200; |
| 3803 | dc->caps.i2c_speed_in_khz = 100; | 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 | dc->caps.max_cursor_size = 256; | 3796 | dc->caps.max_cursor_size = 256; |
| 3797 | dc->caps.min_horizontal_blanking_period = 80; | ||
| 3805 | dc->caps.dmdata_alloc_size = 2048; | 3798 | dc->caps.dmdata_alloc_size = 2048; |
| 3806 | 3799 | ||
| 3807 | dc->caps.max_slave_planes = 1; | 3800 | dc->caps.max_slave_planes = 1; |
| @@ -118,6 +118,9 @@ void dcn20_set_mcif_arb_params( · 117 unmodified lines | |||
| 118 | display_e2e_pipe_params_st *pipes, | 118 | display_e2e_pipe_params_st *pipes, |
| 119 | int pipe_cnt); | 119 | int pipe_cnt); |
| 120 | bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, bool fast_validate); | 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 | int dcn20_validate_apply_pipe_split_flags( | 124 | int dcn20_validate_apply_pipe_split_flags( |
| 122 | struct dc *dc, | 125 | struct dc *dc, |
| 123 | struct dc_state *context, | 126 | struct dc_state *context, |
| @@ -223,3 +223,18 @@ bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx, · 222 unmodified lines | |||
| 223 | return true; | 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 | bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx, | 52 | bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx, |
| 53 | uint32_t backlight_pwm_u16_16, | 53 | uint32_t backlight_pwm_u16_16, |
| 54 | uint32_t frame_ramp); | 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 | #endif /* __DC_HWSS_DCN21_H__ */ | 58 | #endif /* __DC_HWSS_DCN21_H__ */ |
| @@ -35,7 +35,6 @@ static const struct hw_sequencer_funcs dcn21_funcs = { · 34 unmodified lines | |||
| 35 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, | 35 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, |
| 36 | .apply_ctx_for_surface = NULL, | 36 | .apply_ctx_for_surface = NULL, |
| 37 | .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, | 37 | .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, |
| 38 | .disconnect_pipes = dcn10_disconnect_pipes, | ||
| 39 | .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, | 38 | .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, |
| 40 | .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, | 39 | .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, |
| 41 | .update_plane_addr = dcn20_update_plane_addr, | 40 | .update_plane_addr = dcn20_update_plane_addr, |
| @@ -98,6 +97,8 @@ static const struct hw_sequencer_funcs dcn21_funcs = { · 56 unmodified lines | |||
| 98 | #ifndef TRIM_FSFT | 97 | #ifndef TRIM_FSFT |
| 99 | .optimize_timing_for_fsft = dcn20_optimize_timing_for_fsft, | 98 | .optimize_timing_for_fsft = dcn20_optimize_timing_for_fsft, |
| 100 | #endif | 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 | static const struct hwseq_private_funcs dcn21_private_funcs = { | 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 | .xfc_bus_transport_time_us = 4, | 301 | .xfc_bus_transport_time_us = 4, |
| 302 | .xfc_xbuf_latency_tolerance_us = 4, | 302 | .xfc_xbuf_latency_tolerance_us = 4, |
| 303 | .use_urgent_burst_bw = 1, | 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 | #ifndef MAX | 309 | #ifndef MAX |
| @@ -1154,12 +1156,12 @@ void dcn21_calculate_wm( · 846 unmodified lines | |||
| 1154 | &context->bw_ctx.dml, pipes, pipe_cnt); | 1156 | &context->bw_ctx.dml, pipes, pipe_cnt); |
| 1155 | /* WM Set C */ | 1157 | /* WM Set C */ |
| 1156 | table_entry = &bw_params->wm_table.entries[WM_C]; | 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 | calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c, | 1160 | calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c, |
| 1159 | &context->bw_ctx.dml, pipes, pipe_cnt); | 1161 | &context->bw_ctx.dml, pipes, pipe_cnt); |
| 1160 | /* WM Set B */ | 1162 | /* WM Set B */ |
| 1161 | table_entry = &bw_params->wm_table.entries[WM_B]; | 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 | calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b, | 1165 | calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b, |
| 1164 | &context->bw_ctx.dml, pipes, pipe_cnt); | 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 | bool dcn21_validate_bandwidth(struct dc *dc, struct dc_state *context, | 1308 | bool dcn21_validate_bandwidth(struct dc *dc, struct dc_state *context, |
| 1175 | bool fast_validate) | 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 | /*Unsafe due to current pipe merge and split logic*/ | 1323 | /*Unsafe due to current pipe merge and split logic*/ |
| 1190 | ASSERT(context != dc->current_state); | 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 | if (pipe_cnt == 0) | 1328 | if (pipe_cnt == 0) |
| 1195 | goto validate_out; | 1329 | goto validate_out; |
| @@ -1385,95 +1519,89 @@ struct display_stream_compressor *dcn21_dsc_create( · 189 unmodified lines | |||
| 1385 | return &dsc->base; | 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 | static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) | 1549 | static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params) |
| 1389 | { | 1550 | { |
| 1390 | struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool); | 1551 | struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool); |
| 1391 | struct clk_limit_table *clk_table = &bw_params->clk_table; | 1552 | struct clk_limit_table *clk_table = &bw_params->clk_table; |
| 1392 | struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES]; | 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 | int j; | 1555 | int j; |
| 1395 | 1556 | ||
| 1396 | // Default clock levels are used for diags, which may lead to overclocking. | 1557 | dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator; |
| 1397 | if (!IS_DIAG_DC(dc->ctx->dce_environment)) { | 1558 | dcn2_1_ip.max_num_dpp = pool->base.pipe_count; |
| 1398 | dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator; | 1559 | dcn2_1_soc.num_chans = bw_params->num_channels; |
| 1399 | dcn2_1_ip.max_num_dpp = pool->base.pipe_count; | 1560 | |
| 1400 | dcn2_1_soc.num_chans = bw_params->num_channels; | 1561 | ASSERT(clk_table->num_entries); |
| 1401 | 1562 | for (i = 0; i < clk_table->num_entries; i++) { | |
| 1402 | ASSERT(clk_table->num_entries); | 1563 | /* loop backwards*/ |
| 1403 | for (i = 0; i < clk_table->num_entries; i++) { | 1564 | for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) { |
| 1404 | /* loop backwards*/ | 1565 | if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) { |
| 1405 | for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) { | 1566 | closest_clk_lvl = j; |
| 1406 | if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) { | 1567 | break; |
| 1407 | closest_clk_lvl = j; | ||
| 1408 | break; | ||
| 1409 | } | ||
| 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 | dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21); | 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 | static struct pp_smu_funcs *dcn21_pp_smu_create(struct dc_context *ctx) | 1605 | static struct pp_smu_funcs *dcn21_pp_smu_create(struct dc_context *ctx) |
| 1478 | { | 1606 | { |
| 1479 | struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL); | 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 | if (!pp_smu) | 1609 | if (!pp_smu) |
| 1482 | return pp_smu; | 1610 | return pp_smu; |
| 1483 | 1611 | ||
| 1484 | if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment) || IS_DIAG_DC(ctx->dce_environment)) { | 1612 | dm_pp_get_funcs(ctx, pp_smu); |
| 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 { | ||
| 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 | return pp_smu; | 1618 | return pp_smu; |
| 1497 | } | 1619 | } |
| @@ -1808,7 +1930,9 @@ static bool dcn21_resource_construct( · 310 unmodified lines | |||
| 1808 | 1930 | ||
| 1809 | dc->caps.max_downscale_ratio = 200; | 1931 | dc->caps.max_downscale_ratio = 200; |
| 1810 | dc->caps.i2c_speed_in_khz = 100; | 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 | dc->caps.max_cursor_size = 256; | 1934 | dc->caps.max_cursor_size = 256; |
| 1935 | dc->caps.min_horizontal_blanking_period = 80; | ||
| 1812 | dc->caps.dmdata_alloc_size = 2048; | 1936 | dc->caps.dmdata_alloc_size = 2048; |
| 1813 | 1937 | ||
| 1814 | dc->caps.max_slave_planes = 1; | 1938 | dc->caps.max_slave_planes = 1; |
| @@ -52,6 +52,7 @@ IS_OLD_GCC = 1 · 51 unmodified lines | |||
| 52 | endif | 52 | endif |
| 53 | endif | 53 | endif |
| 54 | 54 | ||
| 55 | ifdef CONFIG_X86 | ||
| 55 | ifdef IS_OLD_GCC | 56 | ifdef IS_OLD_GCC |
| 56 | # Stack alignment mismatch, proceed with caution. | 57 | # Stack alignment mismatch, proceed with caution. |
| 57 | # GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 | 58 | # GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 |
| @@ -62,6 +63,7 @@ else · 4 unmodified lines | |||
| 62 | CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o += -msse2 | 63 | CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_resource.o += -msse2 |
| 63 | CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o += -msse2 | 64 | CFLAGS_$(AMDDALPATH)/dc/dcn30/dcn30_optc.o += -msse2 |
| 64 | endif | 65 | endif |
| 66 | endif | ||
| 65 | 67 | ||
| 66 | AMD_DAL_DCN30 = $(addprefix $(AMDDALPATH)/dc/dcn30/,$(DCN30)) | 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 | .dpp_program_degamma_pwl = NULL, | 1358 | .dpp_program_degamma_pwl = NULL, |
| 1359 | .dpp_program_cm_dealpha = dpp3_program_cm_dealpha, | 1359 | .dpp_program_cm_dealpha = dpp3_program_cm_dealpha, |
| 1360 | .dpp_program_cm_bias = dpp3_program_cm_bias, | 1360 | .dpp_program_cm_bias = dpp3_program_cm_bias, |
| 1361 | #if defined(CONFIG_DRM_AMD_DC_DCN3_0) | ||
| 1362 | .dpp_program_blnd_lut = dpp3_program_blnd_lut, | 1361 | .dpp_program_blnd_lut = dpp3_program_blnd_lut, |
| 1363 | .dpp_program_shaper_lut = dpp3_program_shaper, | 1362 | .dpp_program_shaper_lut = dpp3_program_shaper, |
| 1364 | .dpp_program_3dlut = dpp3_program_3dlut, | 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 | .dpp_program_bias_and_scale = NULL, | 1364 | .dpp_program_bias_and_scale = NULL, |
| 1372 | .dpp_cnv_set_alpha_keyer = dpp2_cnv_set_alpha_keyer, | 1365 | .dpp_cnv_set_alpha_keyer = dpp2_cnv_set_alpha_keyer, |
| 1373 | .set_cursor_attributes = dpp3_set_cursor_attributes, | 1366 | .set_cursor_attributes = dpp3_set_cursor_attributes, |
| @@ -585,7 +585,7 @@ void dpp3_cm_set_gamut_remap( · 584 unmodified lines | |||
| 585 | const struct dpp_grph_csc_adjustment *adjust); | 585 | const struct dpp_grph_csc_adjustment *adjust); |
| 586 | 586 | ||
| 587 | void dpp3_set_pre_degam(struct dpp *dpp_base, | 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 | void dpp3_set_cursor_attributes( | 590 | void dpp3_set_cursor_attributes( |
| 591 | struct dpp *dpp_base, | 591 | struct dpp *dpp_base, |
| @@ -384,6 +384,58 @@ void hubbub3_force_wm_propagate_to_pipes(struct hubbub *hubbub) · 383 unmodified lines | |||
| 384 | DCHUBBUB_ARB_VM_ROW_URGENCY_WATERMARK_A, prog_wm_value); | 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 | static const struct hubbub_funcs hubbub30_funcs = { | 439 | static const struct hubbub_funcs hubbub30_funcs = { |
| 388 | .update_dchub = hubbub2_update_dchub, | 440 | .update_dchub = hubbub2_update_dchub, |
| 389 | .init_dchub_sys_ctx = hubbub3_init_dchub_sys_ctx, | 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 | .allow_self_refresh_control = hubbub1_allow_self_refresh_control, | 449 | .allow_self_refresh_control = hubbub1_allow_self_refresh_control, |
| 398 | .is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled, | 450 | .is_allow_self_refresh_enabled = hubbub1_is_allow_self_refresh_enabled, |
| 399 | .force_wm_propagate_to_pipes = hubbub3_force_wm_propagate_to_pipes, | 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 | void hubbub3_construct(struct dcn20_hubbub *hubbub3, | 456 | void hubbub3_construct(struct dcn20_hubbub *hubbub3, |
| @@ -116,4 +116,9 @@ bool hubbub3_program_watermarks( · 115 unmodified lines | |||
| 116 | unsigned int refclk_mhz, | 116 | unsigned int refclk_mhz, |
| 117 | bool safe_to_lower); | 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 | #endif | 124 | #endif |
| @@ -251,6 +251,9 @@ bool hubp3_construct( · 250 unmodified lines | |||
| 251 | const struct dcn_hubp2_shift *hubp_shift, | 251 | const struct dcn_hubp2_shift *hubp_shift, |
| 252 | const struct dcn_hubp2_mask *hubp_mask); | 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 | bool hubp3_program_surface_flip_and_addr( | 257 | bool hubp3_program_surface_flip_and_addr( |
| 255 | struct hubp *hubp, | 258 | struct hubp *hubp, |
| 256 | const struct dc_plane_address *address, | 259 | const struct dc_plane_address *address, |
| @@ -462,6 +462,12 @@ void dcn30_init_hw(struct dc *dc) · 461 unmodified lines | |||
| 462 | hws->funcs.disable_vga(dc->hwseq); | 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 | if (dc->ctx->dc_bios->fw_info_valid) { | 471 | if (dc->ctx->dc_bios->fw_info_valid) { |
| 466 | res_pool->ref_clocks.xtalin_clock_inKhz = | 472 | res_pool->ref_clocks.xtalin_clock_inKhz = |
| 467 | dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency; | 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 | if (hws->funcs.enable_power_gating_plane) | 623 | if (hws->funcs.enable_power_gating_plane) |
| 618 | hws->funcs.enable_power_gating_plane(dc->hwseq, true); | 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 | if (dc->clk_mgr->funcs->notify_wm_ranges) | 629 | if (dc->clk_mgr->funcs->notify_wm_ranges) |
| 621 | dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr); | 630 | dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr); |
| 622 | 631 | ||
| 623 | if (dc->clk_mgr->funcs->set_hard_max_memclk) | 632 | if (dc->clk_mgr->funcs->set_hard_max_memclk) |
| 624 | dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr); | 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 | void dcn30_set_avmute(struct pipe_ctx *pipe_ctx, bool enable) | 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 | bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable) | 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 | if (!dc->ctx->dmub_srv) | 709 | if (!dc->ctx->dmub_srv) |
| 693 | return false; | 710 | return false; |
| 694 | 711 | ||
| @@ -703,11 +720,110 @@ bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable) · 8 unmodified lines | |||
| 703 | /* Fail eligibility on a visible stream */ | 720 | /* Fail eligibility on a visible stream */ |
| 704 | break; | 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 | /* No applicable optimizations */ | 792 | /* No applicable optimizations */ |
| 709 | return false; | 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 | return true; | 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 | bool dcn30_apply_idle_power_optimizations(struct dc *dc, bool enable); | 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 | #endif /* __DC_HWSS_DCN30_H__ */ | 80 | #endif /* __DC_HWSS_DCN30_H__ */ |
| @@ -35,7 +35,6 @@ static const struct hw_sequencer_funcs dcn30_funcs = { · 34 unmodified lines | |||
| 35 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, | 35 | .apply_ctx_to_hw = dce110_apply_ctx_to_hw, |
| 36 | .apply_ctx_for_surface = NULL, | 36 | .apply_ctx_for_surface = NULL, |
| 37 | .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, | 37 | .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, |
| 38 | .disconnect_pipes = dcn10_disconnect_pipes, | ||
| 39 | .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, | 38 | .wait_for_pending_cleared = dcn10_wait_for_pending_cleared, |
| 40 | .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, | 39 | .post_unlock_program_front_end = dcn20_post_unlock_program_front_end, |
| 41 | .update_plane_addr = dcn20_update_plane_addr, | 40 | .update_plane_addr = dcn20_update_plane_addr, |
| @@ -90,9 +89,13 @@ static const struct hw_sequencer_funcs dcn30_funcs = { · 48 unmodified lines | |||
| 90 | .init_vm_ctx = dcn20_init_vm_ctx, | 89 | .init_vm_ctx = dcn20_init_vm_ctx, |
| 91 | .set_flip_control_gsl = dcn20_set_flip_control_gsl, | 90 | .set_flip_control_gsl = dcn20_set_flip_control_gsl, |
| 92 | .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, | 91 | .get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync, |
| 92 | .calc_vupdate_position = dcn10_calc_vupdate_position, | ||
| 93 | .apply_idle_power_optimizations = dcn30_apply_idle_power_optimizations, | 93 | .apply_idle_power_optimizations = dcn30_apply_idle_power_optimizations, |
| 94 | .set_backlight_level = dcn21_set_backlight_level, | 94 | .set_backlight_level = dcn21_set_backlight_level, |
| 95 | .set_abm_immediate_disable = dcn21_set_abm_immediate_disable, | 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 | static const struct hwseq_private_funcs dcn30_private_funcs = { | 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 | struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); | 144 | struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); |
| 145 | 145 | ||
| 146 | REG_SET(MPCC_MEM_PWR_CTRL[mpcc_id], 0, | 146 | if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) { |
| 147 | MPCC_OGAM_MEM_PWR_FORCE, power_on == true ? 0:1); | 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 | static void mpc3_configure_ogam_lut( | 158 | static void mpc3_configure_ogam_lut( |
| @@ -360,6 +368,9 @@ void mpc3_set_output_gamma( · 209 unmodified lines | |||
| 360 | /*we need to program 2 fields here as apposed to 1*/ | 368 | /*we need to program 2 fields here as apposed to 1*/ |
| 361 | REG_UPDATE(MPCC_OGAM_CONTROL[mpcc_id], | 369 | REG_UPDATE(MPCC_OGAM_CONTROL[mpcc_id], |
| 362 | MPCC_OGAM_SELECT, next_mode == LUT_RAM_A ? 0:1); | 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 | void mpc3_set_denorm( | 376 | void mpc3_set_denorm( |
| @@ -801,16 +812,28 @@ static void mpc3_power_on_shaper_3dlut( · 435 unmodified lines | |||
| 801 | uint32_t power_status_shaper = 2; | 812 | uint32_t power_status_shaper = 2; |
| 802 | uint32_t power_status_3dlut = 2; | 813 | uint32_t power_status_3dlut = 2; |
| 803 | struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); | 814 | struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); |
| 815 | int max_retries = 10; | ||
| 804 | 816 | ||
| 805 | if (rmu_idx == 0) { | 817 | if (rmu_idx == 0) { |
| 806 | REG_SET(MPC_RMU_MEM_PWR_CTRL, 0, | 818 | REG_SET(MPC_RMU_MEM_PWR_CTRL, 0, |
| 807 | MPC_RMU0_MEM_PWR_DIS, power_on == true ? 1:0); | 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 | /*read status is not mandatory, it is just for debugging*/ | 826 | /*read status is not mandatory, it is just for debugging*/ |
| 809 | REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_SHAPER_MEM_PWR_STATE, &power_status_shaper); | 827 | REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_SHAPER_MEM_PWR_STATE, &power_status_shaper); |
| 810 | REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_3DLUT_MEM_PWR_STATE, &power_status_3dlut); | 828 | REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_3DLUT_MEM_PWR_STATE, &power_status_3dlut); |
| 811 | } else if (rmu_idx == 1) { | 829 | } else if (rmu_idx == 1) { |
| 812 | REG_SET(MPC_RMU_MEM_PWR_CTRL, 0, | 830 | REG_SET(MPC_RMU_MEM_PWR_CTRL, 0, |
| 813 | MPC_RMU1_MEM_PWR_DIS, power_on == true ? 1:0); | 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 | REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_SHAPER_MEM_PWR_STATE, &power_status_shaper); | 837 | REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_SHAPER_MEM_PWR_STATE, &power_status_shaper); |
| 815 | REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_3DLUT_MEM_PWR_STATE, &power_status_3dlut); | 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 | REG_SET(SHAPER_CONTROL[rmu_idx], 0, MPC_RMU_SHAPER_LUT_MODE, 0); | 861 | REG_SET(SHAPER_CONTROL[rmu_idx], 0, MPC_RMU_SHAPER_LUT_MODE, 0); |
| 839 | return false; | 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 | current_mode = mpc3_get_shaper_current(mpc, rmu_idx); | 868 | current_mode = mpc3_get_shaper_current(mpc, rmu_idx); |
| 842 | 869 | ||
| 843 | if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A) | 870 | if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A) |
| @@ -1196,6 +1223,9 @@ bool mpc3_program_3dlut( · 352 unmodified lines | |||
| 1196 | mpc3_set_3dlut_mode(mpc, mode, is_12bits_color_channel, | 1223 | mpc3_set_3dlut_mode(mpc, mode, is_12bits_color_channel, |
| 1197 | is_17x17x17, rmu_idx); | 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 | return true; | 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 | const struct mpc_funcs dcn30_mpc_funcs = { | 1402 | const struct mpc_funcs dcn30_mpc_funcs = { |
| 1353 | .read_mpcc_state = mpc1_read_mpcc_state, | 1403 | .read_mpcc_state = mpc1_read_mpcc_state, |
| 1354 | .insert_plane = mpc1_insert_plane, | 1404 | .insert_plane = mpc1_insert_plane, |
| 1355 | .remove_mpcc = mpc1_remove_mpcc, | 1405 | .remove_mpcc = mpc1_remove_mpcc, |
| 1356 | .mpc_init = mpc1_mpc_init, | 1406 | .mpc_init = mpc3_mpc_init, |
| 1357 | .mpc_init_single_inst = mpc1_mpc_init_single_inst, | 1407 | .mpc_init_single_inst = mpc1_mpc_init_single_inst, |
| 1358 | .update_blending = mpc2_update_blending, | 1408 | .update_blending = mpc2_update_blending, |
| 1359 | .cursor_lock = mpc1_cursor_lock, | 1409 | .cursor_lock = mpc1_cursor_lock, |
| @@ -300,6 +300,7 @@ · 299 unmodified lines | |||
| 300 | SF(MPCC0_MPCC_STATUS, MPCC_DISABLED, mask_sh),\ | 300 | SF(MPCC0_MPCC_STATUS, MPCC_DISABLED, mask_sh),\ |
| 301 | SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_PWR_FORCE, mask_sh),\ | 301 | SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_PWR_FORCE, mask_sh),\ |
| 302 | SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_PWR_DIS, mask_sh),\ | 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 | SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_MODE, mask_sh),\ | 304 | SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_MODE, mask_sh),\ |
| 304 | SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_CLAMP_MAX_R_CR, mask_sh),\ | 305 | SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_CLAMP_MAX_R_CR, mask_sh),\ |
| 305 | SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_CLAMP_MIN_R_CR, mask_sh),\ | 306 | SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_CLAMP_MIN_R_CR, mask_sh),\ |
| @@ -406,6 +407,8 @@ · 100 unmodified lines | |||
| 406 | SF(MPCC0_MPCC_STATUS, MPCC_DISABLED, mask_sh),\ | 407 | SF(MPCC0_MPCC_STATUS, MPCC_DISABLED, mask_sh),\ |
| 407 | SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_PWR_FORCE, mask_sh),\ | 408 | SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_PWR_FORCE, mask_sh),\ |
| 408 | SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_PWR_DIS, mask_sh),\ | 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 | SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_MODE, mask_sh),\ | 412 | SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_MODE, mask_sh),\ |
| 410 | SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_CLAMP_MAX_R_CR, mask_sh),\ | 413 | SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_CLAMP_MAX_R_CR, mask_sh),\ |
| 411 | SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_CLAMP_MIN_R_CR, mask_sh),\ | 414 | SF(MPC_OUT0_DENORM_CONTROL, MPC_OUT_DENORM_CLAMP_MIN_R_CR, mask_sh),\ |
| @@ -492,10 +495,12 @@ · 80 unmodified lines | |||
| 492 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_MEM_PWR_DIS, mask_sh),\ | 495 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_MEM_PWR_DIS, mask_sh),\ |
| 493 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_SHAPER_MEM_PWR_STATE, mask_sh),\ | 496 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_SHAPER_MEM_PWR_STATE, mask_sh),\ |
| 494 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_3DLUT_MEM_PWR_STATE, mask_sh),\ | 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 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_MEM_PWR_FORCE, mask_sh),\ | 499 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_MEM_PWR_FORCE, mask_sh),\ |
| 496 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_MEM_PWR_DIS, mask_sh),\ | 500 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_MEM_PWR_DIS, mask_sh),\ |
| 497 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_SHAPER_MEM_PWR_STATE, mask_sh),\ | 501 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_SHAPER_MEM_PWR_STATE, mask_sh),\ |
| 498 | SF(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_3DLUT_MEM_PWR_STATE, mask_sh),\ | 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 | SF(MPC_RMU0_SHAPER_CONTROL, MPC_RMU_SHAPER_MODE_CURRENT, mask_sh),\ | 504 | SF(MPC_RMU0_SHAPER_CONTROL, MPC_RMU_SHAPER_MODE_CURRENT, mask_sh),\ |
| 500 | SF(CUR_VUPDATE_LOCK_SET0, CUR_VUPDATE_LOCK_SET, mask_sh) | 505 | SF(CUR_VUPDATE_LOCK_SET0, CUR_VUPDATE_LOCK_SET, mask_sh) |
| 501 | 506 | ||
| @@ -519,10 +524,12 @@ · 17 unmodified lines | |||
| 519 | type MPC_RMU1_MUX_STATUS; \ | 524 | type MPC_RMU1_MUX_STATUS; \ |
| 520 | type MPC_RMU0_MEM_PWR_FORCE;\ | 525 | type MPC_RMU0_MEM_PWR_FORCE;\ |
| 521 | type MPC_RMU0_MEM_PWR_DIS;\ | 526 | type MPC_RMU0_MEM_PWR_DIS;\ |
| 527 | type MPC_RMU0_MEM_LOW_PWR_MODE;\ | ||
| 522 | type MPC_RMU0_SHAPER_MEM_PWR_STATE;\ | 528 | type MPC_RMU0_SHAPER_MEM_PWR_STATE;\ |
| 523 | type MPC_RMU0_3DLUT_MEM_PWR_STATE;\ | 529 | type MPC_RMU0_3DLUT_MEM_PWR_STATE;\ |
| 524 | type MPC_RMU1_MEM_PWR_FORCE;\ | 530 | type MPC_RMU1_MEM_PWR_FORCE;\ |
| 525 | type MPC_RMU1_MEM_PWR_DIS;\ | 531 | type MPC_RMU1_MEM_PWR_DIS;\ |
| 532 | type MPC_RMU1_MEM_LOW_PWR_MODE;\ | ||
| 526 | type MPC_RMU1_SHAPER_MEM_PWR_STATE;\ | 533 | type MPC_RMU1_SHAPER_MEM_PWR_STATE;\ |
| 527 | type MPC_RMU1_3DLUT_MEM_PWR_STATE;\ | 534 | type MPC_RMU1_3DLUT_MEM_PWR_STATE;\ |
| 528 | type MPCC_OGAM_RAMA_EXP_REGION_START_SLOPE_B; \ | 535 | type MPCC_OGAM_RAMA_EXP_REGION_START_SLOPE_B; \ |
| @@ -541,6 +548,8 @@ · 12 unmodified lines | |||
| 541 | type MPCC_OGAM_LUT_CONFIG_MODE; \ | 548 | type MPCC_OGAM_LUT_CONFIG_MODE; \ |
| 542 | type MPCC_OGAM_LUT_STATUS; \ | 549 | type MPCC_OGAM_LUT_STATUS; \ |
| 543 | type MPCC_OGAM_RAMA_START_BASE_CNTL_B;\ | 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 | type MPC_RMU_3DLUT_MODE; \ | 553 | type MPC_RMU_3DLUT_MODE; \ |
| 545 | type MPC_RMU_3DLUT_SIZE; \ | 554 | type MPC_RMU_3DLUT_SIZE; \ |
| 546 | type MPC_RMU_3DLUT_MODE_CURRENT; \ | 555 | type MPC_RMU_3DLUT_MODE_CURRENT; \ |
| @@ -60,6 +60,7 @@ · 59 unmodified lines | |||
| 60 | #include "dml/display_mode_vba.h" | 60 | #include "dml/display_mode_vba.h" |
| 61 | #include "dcn30/dcn30_dccg.h" | 61 | #include "dcn30/dcn30_dccg.h" |
| 62 | #include "dcn10/dcn10_resource.h" | 62 | #include "dcn10/dcn10_resource.h" |
| 63 | #include "dc_link_ddc.h" | ||
| 63 | #include "dce/dce_panel_cntl.h" | 64 | #include "dce/dce_panel_cntl.h" |
| 64 | 65 | ||
| 65 | #include "dcn30/dcn30_dwb.h" | 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 | static const struct dce_abm_shift abm_shift = { | 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 | static const struct dce_abm_mask abm_mask = { | 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 | if (pool->base.dccg != NULL) | 1323 | if (pool->base.dccg != NULL) |
| 1323 | dcn_dccg_destroy(&pool->base.dccg); | 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 | static struct hubp *dcn30_hubp_create( | 1330 | static struct hubp *dcn30_hubp_create( |
| @@ -1465,7 +1469,19 @@ int dcn30_populate_dml_pipes_from_context( · 138 unmodified lines | |||
| 1465 | return pipe_cnt; | 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 | struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes) | 1485 | struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes) |
| 1470 | { | 1486 | { |
| 1471 | int pipe_cnt, i, j; | 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 | unsigned int dcn30_calc_max_scaled_time( | 1581 | unsigned int dcn30_calc_max_scaled_time( |
| 1558 | unsigned int time_per_pixel, | 1582 | unsigned int time_per_pixel, |
| 1559 | enum mmhubbub_wbif_mode mode, | 1583 | enum mmhubbub_wbif_mode mode, |
| @@ -1873,11 +1897,22 @@ static bool dcn30_split_stream_for_mpc_or_odm( · 313 unmodified lines | |||
| 1873 | sec_pipe->next_odm_pipe = pri_pipe->next_odm_pipe; | 1897 | sec_pipe->next_odm_pipe = pri_pipe->next_odm_pipe; |
| 1874 | sec_pipe->next_odm_pipe->prev_odm_pipe = sec_pipe; | 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 | pri_pipe->next_odm_pipe = sec_pipe; | 1908 | pri_pipe->next_odm_pipe = sec_pipe; |
| 1877 | sec_pipe->prev_odm_pipe = pri_pipe; | 1909 | sec_pipe->prev_odm_pipe = pri_pipe; |
| 1878 | ASSERT(sec_pipe->top_pipe == NULL); | 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 | if (sec_pipe->stream->timing.flags.DSC == 1) { | 1916 | if (sec_pipe->stream->timing.flags.DSC == 1) { |
| 1882 | dcn20_acquire_dsc(dc, res_ctx, &sec_pipe->stream_res.dsc, pipe_idx); | 1917 | dcn20_acquire_dsc(dc, res_ctx, &sec_pipe->stream_res.dsc, pipe_idx); |
| 1883 | ASSERT(sec_pipe->stream_res.dsc); | 1918 | ASSERT(sec_pipe->stream_res.dsc); |
| @@ -2005,20 +2040,6 @@ static bool dcn30_internal_validate_bw( · 121 unmodified lines | |||
| 2005 | 2040 | ||
| 2006 | dml_log_mode_support_params(&context->bw_ctx.dml); | 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 | if (vlevel == context->bw_ctx.dml.soc.num_states) | 2043 | if (vlevel == context->bw_ctx.dml.soc.num_states) |
| 2023 | goto validate_fail; | 2044 | goto validate_fail; |
| 2024 | 2045 | ||
| @@ -2203,7 +2224,19 @@ validate_out: · 178 unmodified lines | |||
| 2203 | return out; | 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 | struct dc *dc, struct dc_state *context, | 2240 | struct dc *dc, struct dc_state *context, |
| 2208 | display_e2e_pipe_params_st *pipes, | 2241 | display_e2e_pipe_params_st *pipes, |
| 2209 | int pipe_cnt, | 2242 | int pipe_cnt, |
| @@ -2249,7 +2282,7 @@ void dcn30_calculate_wm_and_dlg( · 39 unmodified lines | |||
| 2249 | /* Set D: | 2282 | /* Set D: |
| 2250 | * DCFCLK: Min Required | 2283 | * DCFCLK: Min Required |
| 2251 | * FCLK(proportional to UCLK): 1GHz or Max | 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 | if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_D].valid) { | 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 | * calculate DLG based on dummy p-state latency, and max out the set A p-state watermark | 2337 | * calculate DLG based on dummy p-state latency, and max out the set A p-state watermark |
| 2305 | */ | 2338 | */ |
| 2306 | context->bw_ctx.bw.dcn.watermarks.a = context->bw_ctx.bw.dcn.watermarks.c; | 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 | } else { | 2341 | } else { |
| 2309 | /* Set A: | 2342 | /* Set A: |
| 2310 | * DCFCLK: Min Required | 2343 | * DCFCLK: Min Required |
| @@ -2359,7 +2392,18 @@ void dcn30_calculate_wm_and_dlg( · 48 unmodified lines | |||
| 2359 | dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us; | 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 | struct dc_state *context, | 2407 | struct dc_state *context, |
| 2364 | bool fast_validate) | 2408 | bool fast_validate) |
| 2365 | { | 2409 | { |
| @@ -2410,7 +2454,20 @@ validate_out: · 44 unmodified lines | |||
| 2410 | return out; | 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 | unsigned int *optimal_dcfclk, | 2471 | unsigned int *optimal_dcfclk, |
| 2415 | unsigned int *optimal_fclk) | 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 | // Calculate optimal dcfclk for each uclk | 2535 | // Calculate optimal dcfclk for each uclk |
| 2479 | for (i = 0; i < num_uclk_states; i++) { | 2536 | for (i = 0; i < num_uclk_states; i++) { |
| 2537 | DC_FP_START(); | ||
| 2480 | get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16, | 2538 | get_optimal_dcfclk_fclk_for_uclk(bw_params->clk_table.entries[i].memclk_mhz * 16, |
| 2481 | &optimal_dcfclk_for_uclk[i], NULL); | 2539 | &optimal_dcfclk_for_uclk[i], NULL); |
| 2540 | DC_FP_END(); | ||
| 2482 | if (optimal_dcfclk_for_uclk[i] < bw_params->clk_table.entries[0].dcfclk_mhz) { | 2541 | if (optimal_dcfclk_for_uclk[i] < bw_params->clk_table.entries[0].dcfclk_mhz) { |
| 2483 | optimal_dcfclk_for_uclk[i] = bw_params->clk_table.entries[0].dcfclk_mhz; | 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 | int i; | 2639 | int i; |
| 2581 | struct dc_context *ctx = dc->ctx; | 2640 | struct dc_context *ctx = dc->ctx; |
| 2582 | struct irq_service_init_data init_data; | 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 | ctx->dc_bios->regs = &bios_regs; | 2646 | ctx->dc_bios->regs = &bios_regs; |
| 2585 | 2647 | ||
| @@ -2595,7 +2657,9 @@ static bool dcn30_resource_construct( · 9 unmodified lines | |||
| 2595 | pool->base.mpcc_count = pool->base.res_cap->num_timing_generator; | 2657 | pool->base.mpcc_count = pool->base.res_cap->num_timing_generator; |
| 2596 | dc->caps.max_downscale_ratio = 600; | 2658 | dc->caps.max_downscale_ratio = 600; |
| 2597 | dc->caps.i2c_speed_in_khz = 100; | 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 | dc->caps.max_cursor_size = 256; | 2661 | dc->caps.max_cursor_size = 256; |
| 2662 | dc->caps.min_horizontal_blanking_period = 80; | ||
| 2599 | dc->caps.dmdata_alloc_size = 2048; | 2663 | dc->caps.dmdata_alloc_size = 2048; |
| 2600 | 2664 | ||
| 2601 | dc->caps.max_slave_planes = 1; | 2665 | dc->caps.max_slave_planes = 1; |
| @@ -2845,10 +2909,24 @@ static bool dcn30_resource_construct( · 243 unmodified lines | |||
| 2845 | 2909 | ||
| 2846 | dc->cap_funcs = cap_funcs; | 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 | return true; | 2925 | return true; |
| 2849 | 2926 | ||
| 2850 | create_fail: | 2927 | create_fail: |
| 2851 | 2928 | ||
| 2929 | DC_FP_END(); | ||
| 2852 | dcn30_resource_destruct(pool); | 2930 | dcn30_resource_destruct(pool); |
| 2853 | 2931 | ||
| 2854 | return false; | 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.