提交 1c7095d2 编写于 作者: S Sean Paul

Merge airlied/drm-next into drm-misc-next

Refresh -misc-next
Signed-off-by: NSean Paul <seanpaul@chromium.org>
Renesas R-Car LVDS Encoder
==========================
These DT bindings describe the LVDS encoder embedded in the Renesas R-Car
Gen2, R-Car Gen3 and RZ/G SoCs.
Required properties:
- compatible : Shall contain one of
- "renesas,r8a7743-lvds" for R8A7743 (RZ/G1M) compatible LVDS encoders
- "renesas,r8a7790-lvds" for R8A7790 (R-Car H2) compatible LVDS encoders
- "renesas,r8a7791-lvds" for R8A7791 (R-Car M2-W) compatible LVDS encoders
- "renesas,r8a7793-lvds" for R8A7793 (R-Car M2-N) compatible LVDS encoders
- "renesas,r8a7795-lvds" for R8A7795 (R-Car H3) compatible LVDS encoders
- "renesas,r8a7796-lvds" for R8A7796 (R-Car M3-W) compatible LVDS encoders
- "renesas,r8a77970-lvds" for R8A77970 (R-Car V3M) compatible LVDS encoders
- "renesas,r8a77995-lvds" for R8A77995 (R-Car D3) compatible LVDS encoders
- reg: Base address and length for the memory-mapped registers
- clocks: A phandle + clock-specifier pair for the functional clock
- resets: A phandle + reset specifier for the module reset
Required nodes:
The LVDS encoder has two video ports. Their connections are modelled using the
OF graph bindings specified in Documentation/devicetree/bindings/graph.txt.
- Video port 0 corresponds to the parallel RGB input
- Video port 1 corresponds to the LVDS output
Each port shall have a single endpoint.
Example:
lvds0: lvds@feb90000 {
compatible = "renesas,r8a7790-lvds";
reg = <0 0xfeb90000 0 0x1c>;
clocks = <&cpg CPG_MOD 726>;
resets = <&cpg 726>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
lvds0_in: endpoint {
remote-endpoint = <&du_out_lvds0>;
};
};
port@1 {
reg = <1>;
lvds0_out: endpoint {
};
};
};
};
...@@ -10,6 +10,7 @@ Optional properties: ...@@ -10,6 +10,7 @@ Optional properties:
- analog: the connector has DVI analog pins - analog: the connector has DVI analog pins
- digital: the connector has DVI digital pins - digital: the connector has DVI digital pins
- dual-link: the connector has pins for DVI dual-link - dual-link: the connector has pins for DVI dual-link
- hpd-gpios: HPD GPIO number
Required nodes: Required nodes:
- Video port for DVI input - Video port for DVI input
......
...@@ -7,8 +7,6 @@ Required properties: ...@@ -7,8 +7,6 @@ Required properties:
- reg: Physical base address and length of the registers of controller - reg: Physical base address and length of the registers of controller
- reg-names: The names of register regions. The following regions are required: - reg-names: The names of register regions. The following regions are required:
* "dsi_ctrl" * "dsi_ctrl"
- qcom,dsi-host-index: The ID of DSI controller hardware instance. This should
be 0 or 1, since we have 2 DSI controllers at most for now.
- interrupts: The interrupt signal from the DSI block. - interrupts: The interrupt signal from the DSI block.
- power-domains: Should be <&mmcc MDSS_GDSC>. - power-domains: Should be <&mmcc MDSS_GDSC>.
- clocks: Phandles to device clocks. - clocks: Phandles to device clocks.
...@@ -22,6 +20,8 @@ Required properties: ...@@ -22,6 +20,8 @@ Required properties:
* "core" * "core"
For DSIv2, we need an additional clock: For DSIv2, we need an additional clock:
* "src" * "src"
For DSI6G v2.0 onwards, we need also need the clock:
* "byte_intf"
- assigned-clocks: Parents of "byte" and "pixel" for the given platform. - assigned-clocks: Parents of "byte" and "pixel" for the given platform.
- assigned-clock-parents: The Byte clock and Pixel clock PLL outputs provided - assigned-clock-parents: The Byte clock and Pixel clock PLL outputs provided
by a DSI PHY block. See [1] for details on clock bindings. by a DSI PHY block. See [1] for details on clock bindings.
...@@ -88,21 +88,35 @@ Required properties: ...@@ -88,21 +88,35 @@ Required properties:
* "qcom,dsi-phy-28nm-lp" * "qcom,dsi-phy-28nm-lp"
* "qcom,dsi-phy-20nm" * "qcom,dsi-phy-20nm"
* "qcom,dsi-phy-28nm-8960" * "qcom,dsi-phy-28nm-8960"
- reg: Physical base address and length of the registers of PLL, PHY and PHY * "qcom,dsi-phy-14nm"
regulator * "qcom,dsi-phy-10nm"
- reg: Physical base address and length of the registers of PLL, PHY. Some
revisions require the PHY regulator base address, whereas others require the
PHY lane base address. See below for each PHY revision.
- reg-names: The names of register regions. The following regions are required: - reg-names: The names of register regions. The following regions are required:
For DSI 28nm HPM/LP/8960 PHYs and 20nm PHY:
* "dsi_pll" * "dsi_pll"
* "dsi_phy" * "dsi_phy"
* "dsi_phy_regulator" * "dsi_phy_regulator"
For DSI 14nm and 10nm PHYs:
* "dsi_pll"
* "dsi_phy"
* "dsi_phy_lane"
- clock-cells: Must be 1. The DSI PHY block acts as a clock provider, creating - clock-cells: Must be 1. The DSI PHY block acts as a clock provider, creating
2 clocks: A byte clock (index 0), and a pixel clock (index 1). 2 clocks: A byte clock (index 0), and a pixel clock (index 1).
- qcom,dsi-phy-index: The ID of DSI PHY hardware instance. This should
be 0 or 1, since we have 2 DSI PHYs at most for now.
- power-domains: Should be <&mmcc MDSS_GDSC>. - power-domains: Should be <&mmcc MDSS_GDSC>.
- clocks: Phandles to device clocks. See [1] for details on clock bindings. - clocks: Phandles to device clocks. See [1] for details on clock bindings.
- clock-names: the following clocks are required: - clock-names: the following clocks are required:
* "iface" * "iface"
For 28nm HPM/LP, 28nm 8960 PHYs:
- vddio-supply: phandle to vdd-io regulator device node
For 20nm PHY:
- vddio-supply: phandle to vdd-io regulator device node - vddio-supply: phandle to vdd-io regulator device node
- vcca-supply: phandle to vcca regulator device node
For 14nm PHY:
- vcca-supply: phandle to vcca regulator device node
For 10nm PHY:
- vdds-supply: phandle to vdds regulator device node
Optional properties: Optional properties:
- qcom,dsi-phy-regulator-ldo-mode: Boolean value indicating if the LDO mode PHY - qcom,dsi-phy-regulator-ldo-mode: Boolean value indicating if the LDO mode PHY
......
...@@ -13,13 +13,10 @@ Required Properties: ...@@ -13,13 +13,10 @@ Required Properties:
- "renesas,du-r8a7794" for R8A7794 (R-Car E2) compatible DU - "renesas,du-r8a7794" for R8A7794 (R-Car E2) compatible DU
- "renesas,du-r8a7795" for R8A7795 (R-Car H3) compatible DU - "renesas,du-r8a7795" for R8A7795 (R-Car H3) compatible DU
- "renesas,du-r8a7796" for R8A7796 (R-Car M3-W) compatible DU - "renesas,du-r8a7796" for R8A7796 (R-Car M3-W) compatible DU
- "renesas,du-r8a77970" for R8A77970 (R-Car V3M) compatible DU
- "renesas,du-r8a77995" for R8A77995 (R-Car D3) compatible DU
- reg: A list of base address and length of each memory resource, one for - reg: the memory-mapped I/O registers base address and length
each entry in the reg-names property.
- reg-names: Name of the memory resources. The DU requires one memory
resource for the DU core (named "du") and one memory resource for each
LVDS encoder (named "lvds.x" with "x" being the LVDS controller numerical
index).
- interrupt-parent: phandle of the parent interrupt controller. - interrupt-parent: phandle of the parent interrupt controller.
- interrupts: Interrupt specifiers for the DU interrupts. - interrupts: Interrupt specifiers for the DU interrupts.
...@@ -29,14 +26,13 @@ Required Properties: ...@@ -29,14 +26,13 @@ Required Properties:
- clock-names: Name of the clocks. This property is model-dependent. - clock-names: Name of the clocks. This property is model-dependent.
- R8A7779 uses a single functional clock. The clock doesn't need to be - R8A7779 uses a single functional clock. The clock doesn't need to be
named. named.
- All other DU instances use one functional clock per channel and one - All other DU instances use one functional clock per channel The
clock per LVDS encoder (if available). The functional clocks must be functional clocks must be named "du.x" with "x" being the channel
named "du.x" with "x" being the channel numerical index. The LVDS clocks numerical index.
must be named "lvds.x" with "x" being the LVDS encoder numerical index. - In addition to the functional clocks, all DU versions also support
- In addition to the functional and encoder clocks, all DU versions also externally supplied pixel clocks. Those clocks are optional. When
support externally supplied pixel clocks. Those clocks are optional. supplied they must be named "dclkin.x" with "x" being the input clock
When supplied they must be named "dclkin.x" with "x" being the input numerical index.
clock numerical index.
- vsps: A list of phandle and channel index tuples to the VSPs that handle - vsps: A list of phandle and channel index tuples to the VSPs that handle
the memory interfaces for the DU channels. The phandle identifies the VSP the memory interfaces for the DU channels. The phandle identifies the VSP
...@@ -63,15 +59,15 @@ corresponding to each DU output. ...@@ -63,15 +59,15 @@ corresponding to each DU output.
R8A7794 (R-Car E2) DPAD 0 DPAD 1 - - R8A7794 (R-Car E2) DPAD 0 DPAD 1 - -
R8A7795 (R-Car H3) DPAD 0 HDMI 0 HDMI 1 LVDS 0 R8A7795 (R-Car H3) DPAD 0 HDMI 0 HDMI 1 LVDS 0
R8A7796 (R-Car M3-W) DPAD 0 HDMI 0 LVDS 0 - R8A7796 (R-Car M3-W) DPAD 0 HDMI 0 LVDS 0 -
R8A77970 (R-Car V3M) DPAD 0 LVDS 0 - -
R8A77995 (R-Car D3) DPAD 0 LVDS 0 LVDS 1 -
Example: R8A7795 (R-Car H3) ES2.0 DU Example: R8A7795 (R-Car H3) ES2.0 DU
du: display@feb00000 { du: display@feb00000 {
compatible = "renesas,du-r8a7795"; compatible = "renesas,du-r8a7795";
reg = <0 0xfeb00000 0 0x80000>, reg = <0 0xfeb00000 0 0x80000>;
<0 0xfeb90000 0 0x14>;
reg-names = "du", "lvds.0";
interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>, interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>,
...@@ -79,9 +75,8 @@ Example: R8A7795 (R-Car H3) ES2.0 DU ...@@ -79,9 +75,8 @@ Example: R8A7795 (R-Car H3) ES2.0 DU
clocks = <&cpg CPG_MOD 724>, clocks = <&cpg CPG_MOD 724>,
<&cpg CPG_MOD 723>, <&cpg CPG_MOD 723>,
<&cpg CPG_MOD 722>, <&cpg CPG_MOD 722>,
<&cpg CPG_MOD 721>, <&cpg CPG_MOD 721>;
<&cpg CPG_MOD 727>; clock-names = "du.0", "du.1", "du.2", "du.3";
clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0";
vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>, <&vspd0 1>; vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>, <&vspd0 1>;
ports { ports {
......
...@@ -87,8 +87,8 @@ Overlay in-kernel API ...@@ -87,8 +87,8 @@ Overlay in-kernel API
The API is quite easy to use. The API is quite easy to use.
1. Call of_overlay_apply() to create and apply an overlay changeset. The return 1. Call of_overlay_fdt_apply() to create and apply an overlay changeset. The
value is an error or a cookie identifying this overlay. return value is an error or a cookie identifying this overlay.
2. Call of_overlay_remove() to remove and cleanup the overlay changeset 2. Call of_overlay_remove() to remove and cleanup the overlay changeset
previously created via the call to of_overlay_apply(). Removal of an overlay previously created via the call to of_overlay_apply(). Removal of an overlay
......
...@@ -450,5 +450,12 @@ See drivers/gpu/drm/amd/display/TODO for tasks. ...@@ -450,5 +450,12 @@ See drivers/gpu/drm/amd/display/TODO for tasks.
Contact: Harry Wentland, Alex Deucher Contact: Harry Wentland, Alex Deucher
i915
----
- Our early/late pm callbacks could be removed in favour of using
device_link_add to model the dependency between i915 and snd_had. See
https://dri.freedesktop.org/docs/drm/driver-api/device_link.html
Outside DRM Outside DRM
=========== ===========
...@@ -766,6 +766,8 @@ F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c ...@@ -766,6 +766,8 @@ F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c
F: drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
F: drivers/gpu/drm/amd/amdkfd/ F: drivers/gpu/drm/amd/amdkfd/
F: drivers/gpu/drm/amd/include/cik_structs.h F: drivers/gpu/drm/amd/include/cik_structs.h
F: drivers/gpu/drm/amd/include/kgd_kfd_interface.h F: drivers/gpu/drm/amd/include/kgd_kfd_interface.h
...@@ -4744,6 +4746,7 @@ F: drivers/gpu/drm/rcar-du/ ...@@ -4744,6 +4746,7 @@ F: drivers/gpu/drm/rcar-du/
F: drivers/gpu/drm/shmobile/ F: drivers/gpu/drm/shmobile/
F: include/linux/platform_data/shmob_drm.h F: include/linux/platform_data/shmob_drm.h
F: Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt F: Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt
F: Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
F: Documentation/devicetree/bindings/display/renesas,du.txt F: Documentation/devicetree/bindings/display/renesas,du.txt
DRM DRIVERS FOR ROCKCHIP DRM DRIVERS FOR ROCKCHIP
......
...@@ -259,7 +259,7 @@ static void __init dtb_apic_setup(void) ...@@ -259,7 +259,7 @@ static void __init dtb_apic_setup(void)
dtb_ioapic_setup(); dtb_ioapic_setup();
} }
#ifdef CONFIG_OF_FLATTREE #ifdef CONFIG_OF_EARLY_FLATTREE
static void __init x86_flattree_get_config(void) static void __init x86_flattree_get_config(void)
{ {
u32 size, map_len; u32 size, map_len;
......
...@@ -171,6 +171,7 @@ void dma_fence_release(struct kref *kref) ...@@ -171,6 +171,7 @@ void dma_fence_release(struct kref *kref)
trace_dma_fence_destroy(fence); trace_dma_fence_destroy(fence);
/* Failed to signal before release, could be a refcounting issue */
WARN_ON(!list_empty(&fence->cb_list)); WARN_ON(!list_empty(&fence->cb_list));
if (fence->ops->release) if (fence->ops->release)
......
...@@ -30,7 +30,6 @@ FULL_AMD_DISPLAY_PATH = $(FULL_AMD_PATH)/$(DISPLAY_FOLDER_NAME) ...@@ -30,7 +30,6 @@ FULL_AMD_DISPLAY_PATH = $(FULL_AMD_PATH)/$(DISPLAY_FOLDER_NAME)
ccflags-y := -I$(FULL_AMD_PATH)/include/asic_reg \ ccflags-y := -I$(FULL_AMD_PATH)/include/asic_reg \
-I$(FULL_AMD_PATH)/include \ -I$(FULL_AMD_PATH)/include \
-I$(FULL_AMD_PATH)/amdgpu \ -I$(FULL_AMD_PATH)/amdgpu \
-I$(FULL_AMD_PATH)/scheduler \
-I$(FULL_AMD_PATH)/powerplay/inc \ -I$(FULL_AMD_PATH)/powerplay/inc \
-I$(FULL_AMD_PATH)/acp/include \ -I$(FULL_AMD_PATH)/acp/include \
-I$(FULL_AMD_DISPLAY_PATH) \ -I$(FULL_AMD_DISPLAY_PATH) \
...@@ -63,7 +62,7 @@ amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \ ...@@ -63,7 +62,7 @@ amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \
amdgpu-$(CONFIG_DRM_AMDGPU_SI)+= si.o gmc_v6_0.o gfx_v6_0.o si_ih.o si_dma.o dce_v6_0.o si_dpm.o si_smc.o amdgpu-$(CONFIG_DRM_AMDGPU_SI)+= si.o gmc_v6_0.o gfx_v6_0.o si_ih.o si_dma.o dce_v6_0.o si_dpm.o si_smc.o
amdgpu-y += \ amdgpu-y += \
vi.o mxgpu_vi.o nbio_v6_1.o soc15.o mxgpu_ai.o nbio_v7_0.o vega10_reg_init.o 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
# add GMC block # add GMC block
amdgpu-y += \ amdgpu-y += \
...@@ -88,8 +87,7 @@ amdgpu-y += \ ...@@ -88,8 +87,7 @@ amdgpu-y += \
# add SMC block # add SMC block
amdgpu-y += \ amdgpu-y += \
amdgpu_dpm.o \ amdgpu_dpm.o
amdgpu_powerplay.o
# add DCE block # add DCE block
amdgpu-y += \ amdgpu-y += \
...@@ -130,6 +128,8 @@ amdgpu-y += \ ...@@ -130,6 +128,8 @@ amdgpu-y += \
# add amdkfd interfaces # add amdkfd interfaces
amdgpu-y += \ amdgpu-y += \
amdgpu_amdkfd.o \ amdgpu_amdkfd.o \
amdgpu_amdkfd_fence.o \
amdgpu_amdkfd_gpuvm.o \
amdgpu_amdkfd_gfx_v8.o amdgpu_amdkfd_gfx_v8.o
# add cgs # add cgs
......
...@@ -68,6 +68,7 @@ ...@@ -68,6 +68,7 @@
#include "amdgpu_vce.h" #include "amdgpu_vce.h"
#include "amdgpu_vcn.h" #include "amdgpu_vcn.h"
#include "amdgpu_mn.h" #include "amdgpu_mn.h"
#include "amdgpu_gmc.h"
#include "amdgpu_dm.h" #include "amdgpu_dm.h"
#include "amdgpu_virt.h" #include "amdgpu_virt.h"
#include "amdgpu_gart.h" #include "amdgpu_gart.h"
...@@ -127,6 +128,7 @@ extern int amdgpu_job_hang_limit; ...@@ -127,6 +128,7 @@ extern int amdgpu_job_hang_limit;
extern int amdgpu_lbpw; extern int amdgpu_lbpw;
extern int amdgpu_compute_multipipe; extern int amdgpu_compute_multipipe;
extern int amdgpu_gpu_recovery; extern int amdgpu_gpu_recovery;
extern int amdgpu_emu_mode;
#ifdef CONFIG_DRM_AMDGPU_SI #ifdef CONFIG_DRM_AMDGPU_SI
extern int amdgpu_si_support; extern int amdgpu_si_support;
...@@ -179,10 +181,6 @@ extern int amdgpu_cik_support; ...@@ -179,10 +181,6 @@ extern int amdgpu_cik_support;
#define CIK_CURSOR_WIDTH 128 #define CIK_CURSOR_WIDTH 128
#define CIK_CURSOR_HEIGHT 128 #define CIK_CURSOR_HEIGHT 128
/* GPU RESET flags */
#define AMDGPU_RESET_INFO_VRAM_LOST (1 << 0)
#define AMDGPU_RESET_INFO_FULLRESET (1 << 1)
struct amdgpu_device; struct amdgpu_device;
struct amdgpu_ib; struct amdgpu_ib;
struct amdgpu_cs_parser; struct amdgpu_cs_parser;
...@@ -318,13 +316,6 @@ struct amdgpu_vm_pte_funcs { ...@@ -318,13 +316,6 @@ struct amdgpu_vm_pte_funcs {
void (*write_pte)(struct amdgpu_ib *ib, uint64_t pe, void (*write_pte)(struct amdgpu_ib *ib, uint64_t pe,
uint64_t value, unsigned count, uint64_t value, unsigned count,
uint32_t incr); uint32_t incr);
/* maximum nums of PTEs/PDEs in a single operation */
uint32_t set_max_nums_pte_pde;
/* number of dw to reserve per operation */
unsigned set_pte_pde_num_dw;
/* for linear pte/pde updates without addr mapping */ /* for linear pte/pde updates without addr mapping */
void (*set_pte_pde)(struct amdgpu_ib *ib, void (*set_pte_pde)(struct amdgpu_ib *ib,
uint64_t pe, uint64_t pe,
...@@ -332,28 +323,6 @@ struct amdgpu_vm_pte_funcs { ...@@ -332,28 +323,6 @@ struct amdgpu_vm_pte_funcs {
uint32_t incr, uint64_t flags); uint32_t incr, uint64_t flags);
}; };
/* provided by the gmc block */
struct amdgpu_gart_funcs {
/* flush the vm tlb via mmio */
void (*flush_gpu_tlb)(struct amdgpu_device *adev,
uint32_t vmid);
/* write pte/pde updates using the cpu */
int (*set_pte_pde)(struct amdgpu_device *adev,
void *cpu_pt_addr, /* cpu addr of page table */
uint32_t gpu_page_idx, /* pte/pde to update */
uint64_t addr, /* addr to write into pte/pde */
uint64_t flags); /* access flags */
/* enable/disable PRT support */
void (*set_prt)(struct amdgpu_device *adev, bool enable);
/* set pte flags based per asic */
uint64_t (*get_vm_pte_flags)(struct amdgpu_device *adev,
uint32_t flags);
/* get the pde for a given mc addr */
void (*get_vm_pde)(struct amdgpu_device *adev, int level,
u64 *dst, u64 *flags);
uint32_t (*get_invalidate_req)(unsigned int vmid);
};
/* provided by the ih block */ /* provided by the ih block */
struct amdgpu_ih_funcs { struct amdgpu_ih_funcs {
/* ring read/write ptr handling, called from interrupt context */ /* ring read/write ptr handling, called from interrupt context */
...@@ -370,14 +339,6 @@ struct amdgpu_ih_funcs { ...@@ -370,14 +339,6 @@ struct amdgpu_ih_funcs {
bool amdgpu_get_bios(struct amdgpu_device *adev); bool amdgpu_get_bios(struct amdgpu_device *adev);
bool amdgpu_read_bios(struct amdgpu_device *adev); bool amdgpu_read_bios(struct amdgpu_device *adev);
/*
* Dummy page
*/
struct amdgpu_dummy_page {
struct page *page;
dma_addr_t addr;
};
/* /*
* Clocks * Clocks
*/ */
...@@ -418,8 +379,8 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev, ...@@ -418,8 +379,8 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
struct dma_buf *amdgpu_gem_prime_export(struct drm_device *dev, struct dma_buf *amdgpu_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *gobj, struct drm_gem_object *gobj,
int flags); int flags);
int amdgpu_gem_prime_pin(struct drm_gem_object *obj); struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev,
void amdgpu_gem_prime_unpin(struct drm_gem_object *obj); struct dma_buf *dma_buf);
struct reservation_object *amdgpu_gem_prime_res_obj(struct drm_gem_object *); struct reservation_object *amdgpu_gem_prime_res_obj(struct drm_gem_object *);
void *amdgpu_gem_prime_vmap(struct drm_gem_object *obj); void *amdgpu_gem_prime_vmap(struct drm_gem_object *obj);
void amdgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); void amdgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
...@@ -480,7 +441,7 @@ struct amdgpu_sa_bo { ...@@ -480,7 +441,7 @@ struct amdgpu_sa_bo {
void amdgpu_gem_force_release(struct amdgpu_device *adev); void amdgpu_gem_force_release(struct amdgpu_device *adev);
int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size, int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,
int alignment, u32 initial_domain, int alignment, u32 initial_domain,
u64 flags, bool kernel, u64 flags, enum ttm_bo_type type,
struct reservation_object *resv, struct reservation_object *resv,
struct drm_gem_object **obj); struct drm_gem_object **obj);
...@@ -493,56 +454,6 @@ int amdgpu_mode_dumb_mmap(struct drm_file *filp, ...@@ -493,56 +454,6 @@ int amdgpu_mode_dumb_mmap(struct drm_file *filp,
int amdgpu_fence_slab_init(void); int amdgpu_fence_slab_init(void);
void amdgpu_fence_slab_fini(void); void amdgpu_fence_slab_fini(void);
/*
* VMHUB structures, functions & helpers
*/
struct amdgpu_vmhub {
uint32_t ctx0_ptb_addr_lo32;
uint32_t ctx0_ptb_addr_hi32;
uint32_t vm_inv_eng0_req;
uint32_t vm_inv_eng0_ack;
uint32_t vm_context0_cntl;
uint32_t vm_l2_pro_fault_status;
uint32_t vm_l2_pro_fault_cntl;
};
/*
* GPU MC structures, functions & helpers
*/
struct amdgpu_mc {
resource_size_t aper_size;
resource_size_t aper_base;
resource_size_t agp_base;
/* for some chips with <= 32MB we need to lie
* about vram size near mc fb location */
u64 mc_vram_size;
u64 visible_vram_size;
u64 gart_size;
u64 gart_start;
u64 gart_end;
u64 vram_start;
u64 vram_end;
unsigned vram_width;
u64 real_vram_size;
int vram_mtrr;
u64 mc_mask;
const struct firmware *fw; /* MC firmware */
uint32_t fw_version;
struct amdgpu_irq_src vm_fault;
uint32_t vram_type;
uint32_t srbm_soft_reset;
bool prt_warning;
uint64_t stolen_size;
/* apertures */
u64 shared_aperture_start;
u64 shared_aperture_end;
u64 private_aperture_start;
u64 private_aperture_end;
/* protects concurrent invalidation */
spinlock_t invalidate_lock;
bool translate_further;
};
/* /*
* GPU doorbell structures, functions & helpers * GPU doorbell structures, functions & helpers
*/ */
...@@ -1125,8 +1036,9 @@ struct amdgpu_job { ...@@ -1125,8 +1036,9 @@ struct amdgpu_job {
void *owner; void *owner;
uint64_t fence_ctx; /* the fence_context this job uses */ uint64_t fence_ctx; /* the fence_context this job uses */
bool vm_needs_flush; bool vm_needs_flush;
unsigned vmid;
uint64_t vm_pd_addr; uint64_t vm_pd_addr;
unsigned vmid;
unsigned pasid;
uint32_t gds_base, gds_size; uint32_t gds_base, gds_size;
uint32_t gws_base, gws_size; uint32_t gws_base, gws_size;
uint32_t oa_base, oa_size; uint32_t oa_base, oa_size;
...@@ -1156,7 +1068,7 @@ static inline void amdgpu_set_ib_value(struct amdgpu_cs_parser *p, ...@@ -1156,7 +1068,7 @@ static inline void amdgpu_set_ib_value(struct amdgpu_cs_parser *p,
/* /*
* Writeback * Writeback
*/ */
#define AMDGPU_MAX_WB 512 /* Reserve at most 512 WB slots for amdgpu-owned rings. */ #define AMDGPU_MAX_WB 128 /* Reserve at most 128 WB slots for amdgpu-owned rings. */
struct amdgpu_wb { struct amdgpu_wb {
struct amdgpu_bo *wb_obj; struct amdgpu_bo *wb_obj;
...@@ -1169,8 +1081,6 @@ struct amdgpu_wb { ...@@ -1169,8 +1081,6 @@ struct amdgpu_wb {
int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb); int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb);
void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb); void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb);
void amdgpu_device_get_pcie_info(struct amdgpu_device *adev);
/* /*
* SDMA * SDMA
*/ */
...@@ -1288,6 +1198,11 @@ struct amdgpu_asic_funcs { ...@@ -1288,6 +1198,11 @@ struct amdgpu_asic_funcs {
void (*set_pcie_lanes)(struct amdgpu_device *adev, int lanes); void (*set_pcie_lanes)(struct amdgpu_device *adev, int lanes);
/* get config memsize register */ /* get config memsize register */
u32 (*get_config_memsize)(struct amdgpu_device *adev); u32 (*get_config_memsize)(struct amdgpu_device *adev);
/* flush hdp write queue */
void (*flush_hdp)(struct amdgpu_device *adev, struct amdgpu_ring *ring);
/* invalidate hdp read cache */
void (*invalidate_hdp)(struct amdgpu_device *adev,
struct amdgpu_ring *ring);
}; };
/* /*
...@@ -1431,7 +1346,7 @@ struct amdgpu_nbio_funcs { ...@@ -1431,7 +1346,7 @@ struct amdgpu_nbio_funcs {
u32 (*get_pcie_data_offset)(struct amdgpu_device *adev); u32 (*get_pcie_data_offset)(struct amdgpu_device *adev);
u32 (*get_rev_id)(struct amdgpu_device *adev); u32 (*get_rev_id)(struct amdgpu_device *adev);
void (*mc_access_enable)(struct amdgpu_device *adev, bool enable); void (*mc_access_enable)(struct amdgpu_device *adev, bool enable);
void (*hdp_flush)(struct amdgpu_device *adev); void (*hdp_flush)(struct amdgpu_device *adev, struct amdgpu_ring *ring);
u32 (*get_memsize)(struct amdgpu_device *adev); u32 (*get_memsize)(struct amdgpu_device *adev);
void (*sdma_doorbell_range)(struct amdgpu_device *adev, int instance, void (*sdma_doorbell_range)(struct amdgpu_device *adev, int instance,
bool use_doorbell, int doorbell_index); bool use_doorbell, int doorbell_index);
...@@ -1478,9 +1393,7 @@ enum amd_hw_ip_block_type { ...@@ -1478,9 +1393,7 @@ enum amd_hw_ip_block_type {
#define HWIP_MAX_INSTANCE 6 #define HWIP_MAX_INSTANCE 6
struct amd_powerplay { struct amd_powerplay {
struct cgs_device *cgs_device;
void *pp_handle; void *pp_handle;
const struct amd_ip_funcs *ip_funcs;
const struct amd_pm_funcs *pp_funcs; const struct amd_pm_funcs *pp_funcs;
}; };
...@@ -1574,9 +1487,9 @@ struct amdgpu_device { ...@@ -1574,9 +1487,9 @@ struct amdgpu_device {
struct amdgpu_clock clock; struct amdgpu_clock clock;
/* MC */ /* MC */
struct amdgpu_mc mc; struct amdgpu_gmc gmc;
struct amdgpu_gart gart; struct amdgpu_gart gart;
struct amdgpu_dummy_page dummy_page; dma_addr_t dummy_page_addr;
struct amdgpu_vm_manager vm_manager; struct amdgpu_vm_manager vm_manager;
struct amdgpu_vmhub vmhub[AMDGPU_MAX_VMHUBS]; struct amdgpu_vmhub vmhub[AMDGPU_MAX_VMHUBS];
...@@ -1715,6 +1628,9 @@ uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg, ...@@ -1715,6 +1628,9 @@ uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
uint32_t acc_flags); uint32_t acc_flags);
void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
uint32_t acc_flags); uint32_t acc_flags);
void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value);
uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset);
u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg); u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg);
void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v); void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v);
...@@ -1726,6 +1642,8 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v); ...@@ -1726,6 +1642,8 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v);
bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type); bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type);
bool amdgpu_device_has_dc_support(struct amdgpu_device *adev); bool amdgpu_device_has_dc_support(struct amdgpu_device *adev);
int emu_soc_asic_init(struct amdgpu_device *adev);
/* /*
* Registers read & write functions. * Registers read & write functions.
*/ */
...@@ -1736,6 +1654,9 @@ bool amdgpu_device_has_dc_support(struct amdgpu_device *adev); ...@@ -1736,6 +1654,9 @@ bool amdgpu_device_has_dc_support(struct amdgpu_device *adev);
#define RREG32_NO_KIQ(reg) amdgpu_mm_rreg(adev, (reg), AMDGPU_REGS_NO_KIQ) #define RREG32_NO_KIQ(reg) amdgpu_mm_rreg(adev, (reg), AMDGPU_REGS_NO_KIQ)
#define WREG32_NO_KIQ(reg, v) amdgpu_mm_wreg(adev, (reg), (v), AMDGPU_REGS_NO_KIQ) #define WREG32_NO_KIQ(reg, v) amdgpu_mm_wreg(adev, (reg), (v), AMDGPU_REGS_NO_KIQ)
#define RREG8(reg) amdgpu_mm_rreg8(adev, (reg))
#define WREG8(reg, v) amdgpu_mm_wreg8(adev, (reg), (v))
#define RREG32(reg) amdgpu_mm_rreg(adev, (reg), 0) #define RREG32(reg) amdgpu_mm_rreg(adev, (reg), 0)
#define RREG32_IDX(reg) amdgpu_mm_rreg(adev, (reg), AMDGPU_REGS_IDX) #define RREG32_IDX(reg) amdgpu_mm_rreg(adev, (reg), AMDGPU_REGS_IDX)
#define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", amdgpu_mm_rreg(adev, (reg), 0)) #define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", amdgpu_mm_rreg(adev, (reg), 0))
...@@ -1838,13 +1759,17 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) ...@@ -1838,13 +1759,17 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
#define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l)) #define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l))
#define amdgpu_asic_read_register(adev, se, sh, offset, v)((adev)->asic_funcs->read_register((adev), (se), (sh), (offset), (v))) #define amdgpu_asic_read_register(adev, se, sh, offset, v)((adev)->asic_funcs->read_register((adev), (se), (sh), (offset), (v)))
#define amdgpu_asic_get_config_memsize(adev) (adev)->asic_funcs->get_config_memsize((adev)) #define amdgpu_asic_get_config_memsize(adev) (adev)->asic_funcs->get_config_memsize((adev))
#define amdgpu_gart_flush_gpu_tlb(adev, vmid) (adev)->gart.gart_funcs->flush_gpu_tlb((adev), (vmid)) #define amdgpu_asic_flush_hdp(adev, r) (adev)->asic_funcs->flush_hdp((adev), (r))
#define amdgpu_gart_set_pte_pde(adev, pt, idx, addr, flags) (adev)->gart.gart_funcs->set_pte_pde((adev), (pt), (idx), (addr), (flags)) #define amdgpu_asic_invalidate_hdp(adev, r) (adev)->asic_funcs->invalidate_hdp((adev), (r))
#define amdgpu_gart_get_vm_pde(adev, level, dst, flags) (adev)->gart.gart_funcs->get_vm_pde((adev), (level), (dst), (flags)) #define amdgpu_gmc_flush_gpu_tlb(adev, vmid) (adev)->gmc.gmc_funcs->flush_gpu_tlb((adev), (vmid))
#define amdgpu_gmc_emit_flush_gpu_tlb(r, vmid, addr) (r)->adev->gmc.gmc_funcs->emit_flush_gpu_tlb((r), (vmid), (addr))
#define amdgpu_gmc_emit_pasid_mapping(r, vmid, pasid) (r)->adev->gmc.gmc_funcs->emit_pasid_mapping((r), (vmid), (pasid))
#define amdgpu_gmc_set_pte_pde(adev, pt, idx, addr, flags) (adev)->gmc.gmc_funcs->set_pte_pde((adev), (pt), (idx), (addr), (flags))
#define amdgpu_gmc_get_vm_pde(adev, level, dst, flags) (adev)->gmc.gmc_funcs->get_vm_pde((adev), (level), (dst), (flags))
#define amdgpu_gmc_get_pte_flags(adev, flags) (adev)->gmc.gmc_funcs->get_vm_pte_flags((adev),(flags))
#define amdgpu_vm_copy_pte(adev, ib, pe, src, count) ((adev)->vm_manager.vm_pte_funcs->copy_pte((ib), (pe), (src), (count))) #define amdgpu_vm_copy_pte(adev, ib, pe, src, count) ((adev)->vm_manager.vm_pte_funcs->copy_pte((ib), (pe), (src), (count)))
#define amdgpu_vm_write_pte(adev, ib, pe, value, count, incr) ((adev)->vm_manager.vm_pte_funcs->write_pte((ib), (pe), (value), (count), (incr))) #define amdgpu_vm_write_pte(adev, ib, pe, value, count, incr) ((adev)->vm_manager.vm_pte_funcs->write_pte((ib), (pe), (value), (count), (incr)))
#define amdgpu_vm_set_pte_pde(adev, ib, pe, addr, count, incr, flags) ((adev)->vm_manager.vm_pte_funcs->set_pte_pde((ib), (pe), (addr), (count), (incr), (flags))) #define amdgpu_vm_set_pte_pde(adev, ib, pe, addr, count, incr, flags) ((adev)->vm_manager.vm_pte_funcs->set_pte_pde((ib), (pe), (addr), (count), (incr), (flags)))
#define amdgpu_vm_get_pte_flags(adev, flags) (adev)->gart.gart_funcs->get_vm_pte_flags((adev),(flags))
#define amdgpu_ring_parse_cs(r, p, ib) ((r)->funcs->parse_cs((p), (ib))) #define amdgpu_ring_parse_cs(r, p, ib) ((r)->funcs->parse_cs((p), (ib)))
#define amdgpu_ring_test_ring(r) (r)->funcs->test_ring((r)) #define amdgpu_ring_test_ring(r) (r)->funcs->test_ring((r))
#define amdgpu_ring_test_ib(r, t) (r)->funcs->test_ib((r), (t)) #define amdgpu_ring_test_ib(r, t) (r)->funcs->test_ib((r), (t))
...@@ -1857,11 +1782,11 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) ...@@ -1857,11 +1782,11 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
#define amdgpu_ring_emit_fence(r, addr, seq, flags) (r)->funcs->emit_fence((r), (addr), (seq), (flags)) #define amdgpu_ring_emit_fence(r, addr, seq, flags) (r)->funcs->emit_fence((r), (addr), (seq), (flags))
#define amdgpu_ring_emit_gds_switch(r, v, db, ds, wb, ws, ab, as) (r)->funcs->emit_gds_switch((r), (v), (db), (ds), (wb), (ws), (ab), (as)) #define amdgpu_ring_emit_gds_switch(r, v, db, ds, wb, ws, ab, as) (r)->funcs->emit_gds_switch((r), (v), (db), (ds), (wb), (ws), (ab), (as))
#define amdgpu_ring_emit_hdp_flush(r) (r)->funcs->emit_hdp_flush((r)) #define amdgpu_ring_emit_hdp_flush(r) (r)->funcs->emit_hdp_flush((r))
#define amdgpu_ring_emit_hdp_invalidate(r) (r)->funcs->emit_hdp_invalidate((r))
#define amdgpu_ring_emit_switch_buffer(r) (r)->funcs->emit_switch_buffer((r)) #define amdgpu_ring_emit_switch_buffer(r) (r)->funcs->emit_switch_buffer((r))
#define amdgpu_ring_emit_cntxcntl(r, d) (r)->funcs->emit_cntxcntl((r), (d)) #define amdgpu_ring_emit_cntxcntl(r, d) (r)->funcs->emit_cntxcntl((r), (d))
#define amdgpu_ring_emit_rreg(r, d) (r)->funcs->emit_rreg((r), (d)) #define amdgpu_ring_emit_rreg(r, d) (r)->funcs->emit_rreg((r), (d))
#define amdgpu_ring_emit_wreg(r, d, v) (r)->funcs->emit_wreg((r), (d), (v)) #define amdgpu_ring_emit_wreg(r, d, v) (r)->funcs->emit_wreg((r), (d), (v))
#define amdgpu_ring_emit_reg_wait(r, d, v, m) (r)->funcs->emit_reg_wait((r), (d), (v), (m))
#define amdgpu_ring_emit_tmz(r, b) (r)->funcs->emit_tmz((r), (b)) #define amdgpu_ring_emit_tmz(r, b) (r)->funcs->emit_tmz((r), (b))
#define amdgpu_ring_pad_ib(r, ib) ((r)->funcs->pad_ib((r), (ib))) #define amdgpu_ring_pad_ib(r, ib) ((r)->funcs->pad_ib((r), (ib)))
#define amdgpu_ring_init_cond_exec(r) (r)->funcs->init_cond_exec((r)) #define amdgpu_ring_init_cond_exec(r) (r)->funcs->init_cond_exec((r))
...@@ -1871,7 +1796,6 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) ...@@ -1871,7 +1796,6 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
#define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv)) #define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv))
#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev)) #define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev))
#define amdgpu_display_vblank_get_counter(adev, crtc) (adev)->mode_info.funcs->vblank_get_counter((adev), (crtc)) #define amdgpu_display_vblank_get_counter(adev, crtc) (adev)->mode_info.funcs->vblank_get_counter((adev), (crtc))
#define amdgpu_display_vblank_wait(adev, crtc) (adev)->mode_info.funcs->vblank_wait((adev), (crtc))
#define amdgpu_display_backlight_set_level(adev, e, l) (adev)->mode_info.funcs->backlight_set_level((e), (l)) #define amdgpu_display_backlight_set_level(adev, e, l) (adev)->mode_info.funcs->backlight_set_level((e), (l))
#define amdgpu_display_backlight_get_level(adev, e) (adev)->mode_info.funcs->backlight_get_level((e)) #define amdgpu_display_backlight_get_level(adev, e) (adev)->mode_info.funcs->backlight_get_level((e))
#define amdgpu_display_hpd_sense(adev, h) (adev)->mode_info.funcs->hpd_sense((adev), (h)) #define amdgpu_display_hpd_sense(adev, h) (adev)->mode_info.funcs->hpd_sense((adev), (h))
...@@ -1894,20 +1818,17 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, ...@@ -1894,20 +1818,17 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
struct amdgpu_job* job, bool force); struct amdgpu_job* job, bool force);
void amdgpu_device_pci_config_reset(struct amdgpu_device *adev); void amdgpu_device_pci_config_reset(struct amdgpu_device *adev);
bool amdgpu_device_need_post(struct amdgpu_device *adev); bool amdgpu_device_need_post(struct amdgpu_device *adev);
void amdgpu_update_display_priority(struct amdgpu_device *adev); void amdgpu_display_update_priority(struct amdgpu_device *adev);
void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes, void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes,
u64 num_vis_bytes); u64 num_vis_bytes);
void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *abo, u32 domain); void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *abo, u32 domain);
bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo); bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo);
void amdgpu_device_vram_location(struct amdgpu_device *adev, void amdgpu_device_vram_location(struct amdgpu_device *adev,
struct amdgpu_mc *mc, u64 base); struct amdgpu_gmc *mc, u64 base);
void amdgpu_device_gart_location(struct amdgpu_device *adev, void amdgpu_device_gart_location(struct amdgpu_device *adev,
struct amdgpu_mc *mc); struct amdgpu_gmc *mc);
int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev); int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev);
void amdgpu_ttm_set_active_vram_size(struct amdgpu_device *adev, u64 size);
int amdgpu_ttm_init(struct amdgpu_device *adev);
void amdgpu_ttm_fini(struct amdgpu_device *adev);
void amdgpu_device_program_register_sequence(struct amdgpu_device *adev, void amdgpu_device_program_register_sequence(struct amdgpu_device *adev,
const u32 *registers, const u32 *registers,
const u32 array_size); const u32 array_size);
......
...@@ -540,6 +540,9 @@ int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev, ...@@ -540,6 +540,9 @@ int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev,
size_t size; size_t size;
u32 retry = 3; u32 retry = 3;
if (amdgpu_acpi_pcie_notify_device_ready(adev))
return -EINVAL;
/* Get the device handle */ /* Get the device handle */
handle = ACPI_HANDLE(&adev->pdev->dev); handle = ACPI_HANDLE(&adev->pdev->dev);
if (!handle) if (!handle)
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
const struct kgd2kfd_calls *kgd2kfd; const struct kgd2kfd_calls *kgd2kfd;
bool (*kgd2kfd_init_p)(unsigned int, const struct kgd2kfd_calls**); bool (*kgd2kfd_init_p)(unsigned int, const struct kgd2kfd_calls**);
static const unsigned int compute_vmid_bitmap = 0xFF00;
int amdgpu_amdkfd_init(void) int amdgpu_amdkfd_init(void)
{ {
int ret; int ret;
...@@ -56,6 +58,7 @@ int amdgpu_amdkfd_init(void) ...@@ -56,6 +58,7 @@ int amdgpu_amdkfd_init(void)
#else #else
ret = -ENOENT; ret = -ENOENT;
#endif #endif
amdgpu_amdkfd_gpuvm_init_mem_limits();
return ret; return ret;
} }
...@@ -78,10 +81,15 @@ void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev) ...@@ -78,10 +81,15 @@ void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev)
switch (adev->asic_type) { switch (adev->asic_type) {
#ifdef CONFIG_DRM_AMDGPU_CIK #ifdef CONFIG_DRM_AMDGPU_CIK
case CHIP_KAVERI: case CHIP_KAVERI:
case CHIP_HAWAII:
kfd2kgd = amdgpu_amdkfd_gfx_7_get_functions(); kfd2kgd = amdgpu_amdkfd_gfx_7_get_functions();
break; break;
#endif #endif
case CHIP_CARRIZO: case CHIP_CARRIZO:
case CHIP_TONGA:
case CHIP_FIJI:
case CHIP_POLARIS10:
case CHIP_POLARIS11:
kfd2kgd = amdgpu_amdkfd_gfx_8_0_get_functions(); kfd2kgd = amdgpu_amdkfd_gfx_8_0_get_functions();
break; break;
default: default:
...@@ -132,9 +140,13 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev) ...@@ -132,9 +140,13 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
int last_valid_bit; int last_valid_bit;
if (adev->kfd) { if (adev->kfd) {
struct kgd2kfd_shared_resources gpu_resources = { struct kgd2kfd_shared_resources gpu_resources = {
.compute_vmid_bitmap = 0xFF00, .compute_vmid_bitmap = compute_vmid_bitmap,
.num_pipe_per_mec = adev->gfx.mec.num_pipe_per_mec, .num_pipe_per_mec = adev->gfx.mec.num_pipe_per_mec,
.num_queue_per_pipe = adev->gfx.mec.num_queue_per_pipe .num_queue_per_pipe = adev->gfx.mec.num_queue_per_pipe,
.gpuvm_size = min(adev->vm_manager.max_pfn
<< AMDGPU_GPU_PAGE_SHIFT,
AMDGPU_VA_HOLE_START),
.drm_render_minor = adev->ddev->render->index
}; };
/* this is going to have a few of the MSBs set that we need to /* this is going to have a few of the MSBs set that we need to
...@@ -204,20 +216,14 @@ int alloc_gtt_mem(struct kgd_dev *kgd, size_t size, ...@@ -204,20 +216,14 @@ int alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
void **cpu_ptr) void **cpu_ptr)
{ {
struct amdgpu_device *adev = (struct amdgpu_device *)kgd; struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
struct kgd_mem **mem = (struct kgd_mem **) mem_obj; struct amdgpu_bo *bo = NULL;
int r; int r;
uint64_t gpu_addr_tmp = 0;
void *cpu_ptr_tmp = NULL;
BUG_ON(kgd == NULL); r = amdgpu_bo_create(adev, size, PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
BUG_ON(gpu_addr == NULL); AMDGPU_GEM_CREATE_CPU_GTT_USWC, ttm_bo_type_kernel,
BUG_ON(cpu_ptr == NULL); NULL, &bo);
*mem = kmalloc(sizeof(struct kgd_mem), GFP_KERNEL);
if ((*mem) == NULL)
return -ENOMEM;
r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_GTT,
AMDGPU_GEM_CREATE_CPU_GTT_USWC, NULL, NULL, 0,
&(*mem)->bo);
if (r) { if (r) {
dev_err(adev->dev, dev_err(adev->dev,
"failed to allocate BO for amdkfd (%d)\n", r); "failed to allocate BO for amdkfd (%d)\n", r);
...@@ -225,54 +231,53 @@ int alloc_gtt_mem(struct kgd_dev *kgd, size_t size, ...@@ -225,54 +231,53 @@ int alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
} }
/* map the buffer */ /* map the buffer */
r = amdgpu_bo_reserve((*mem)->bo, true); r = amdgpu_bo_reserve(bo, true);
if (r) { if (r) {
dev_err(adev->dev, "(%d) failed to reserve bo for amdkfd\n", r); dev_err(adev->dev, "(%d) failed to reserve bo for amdkfd\n", r);
goto allocate_mem_reserve_bo_failed; goto allocate_mem_reserve_bo_failed;
} }
r = amdgpu_bo_pin((*mem)->bo, AMDGPU_GEM_DOMAIN_GTT, r = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT,
&(*mem)->gpu_addr); &gpu_addr_tmp);
if (r) { if (r) {
dev_err(adev->dev, "(%d) failed to pin bo for amdkfd\n", r); dev_err(adev->dev, "(%d) failed to pin bo for amdkfd\n", r);
goto allocate_mem_pin_bo_failed; goto allocate_mem_pin_bo_failed;
} }
*gpu_addr = (*mem)->gpu_addr;
r = amdgpu_bo_kmap((*mem)->bo, &(*mem)->cpu_ptr); r = amdgpu_bo_kmap(bo, &cpu_ptr_tmp);
if (r) { if (r) {
dev_err(adev->dev, dev_err(adev->dev,
"(%d) failed to map bo to kernel for amdkfd\n", r); "(%d) failed to map bo to kernel for amdkfd\n", r);
goto allocate_mem_kmap_bo_failed; goto allocate_mem_kmap_bo_failed;
} }
*cpu_ptr = (*mem)->cpu_ptr;
amdgpu_bo_unreserve((*mem)->bo); *mem_obj = bo;
*gpu_addr = gpu_addr_tmp;
*cpu_ptr = cpu_ptr_tmp;
amdgpu_bo_unreserve(bo);
return 0; return 0;
allocate_mem_kmap_bo_failed: allocate_mem_kmap_bo_failed:
amdgpu_bo_unpin((*mem)->bo); amdgpu_bo_unpin(bo);
allocate_mem_pin_bo_failed: allocate_mem_pin_bo_failed:
amdgpu_bo_unreserve((*mem)->bo); amdgpu_bo_unreserve(bo);
allocate_mem_reserve_bo_failed: allocate_mem_reserve_bo_failed:
amdgpu_bo_unref(&(*mem)->bo); amdgpu_bo_unref(&bo);
return r; return r;
} }
void free_gtt_mem(struct kgd_dev *kgd, void *mem_obj) void free_gtt_mem(struct kgd_dev *kgd, void *mem_obj)
{ {
struct kgd_mem *mem = (struct kgd_mem *) mem_obj; struct amdgpu_bo *bo = (struct amdgpu_bo *) mem_obj;
BUG_ON(mem == NULL);
amdgpu_bo_reserve(mem->bo, true); amdgpu_bo_reserve(bo, true);
amdgpu_bo_kunmap(mem->bo); amdgpu_bo_kunmap(bo);
amdgpu_bo_unpin(mem->bo); amdgpu_bo_unpin(bo);
amdgpu_bo_unreserve(mem->bo); amdgpu_bo_unreserve(bo);
amdgpu_bo_unref(&(mem->bo)); amdgpu_bo_unref(&(bo));
kfree(mem);
} }
void get_local_mem_info(struct kgd_dev *kgd, void get_local_mem_info(struct kgd_dev *kgd,
...@@ -281,24 +286,29 @@ void get_local_mem_info(struct kgd_dev *kgd, ...@@ -281,24 +286,29 @@ void get_local_mem_info(struct kgd_dev *kgd,
struct amdgpu_device *adev = (struct amdgpu_device *)kgd; struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
uint64_t address_mask = adev->dev->dma_mask ? ~*adev->dev->dma_mask : uint64_t address_mask = adev->dev->dma_mask ? ~*adev->dev->dma_mask :
~((1ULL << 32) - 1); ~((1ULL << 32) - 1);
resource_size_t aper_limit = adev->mc.aper_base + adev->mc.aper_size; resource_size_t aper_limit = adev->gmc.aper_base + adev->gmc.aper_size;
memset(mem_info, 0, sizeof(*mem_info)); memset(mem_info, 0, sizeof(*mem_info));
if (!(adev->mc.aper_base & address_mask || aper_limit & address_mask)) { if (!(adev->gmc.aper_base & address_mask || aper_limit & address_mask)) {
mem_info->local_mem_size_public = adev->mc.visible_vram_size; mem_info->local_mem_size_public = adev->gmc.visible_vram_size;
mem_info->local_mem_size_private = adev->mc.real_vram_size - mem_info->local_mem_size_private = adev->gmc.real_vram_size -
adev->mc.visible_vram_size; adev->gmc.visible_vram_size;
} else { } else {
mem_info->local_mem_size_public = 0; mem_info->local_mem_size_public = 0;
mem_info->local_mem_size_private = adev->mc.real_vram_size; mem_info->local_mem_size_private = adev->gmc.real_vram_size;
} }
mem_info->vram_width = adev->mc.vram_width; mem_info->vram_width = adev->gmc.vram_width;
pr_debug("Address base: %pap limit %pap public 0x%llx private 0x%llx\n", pr_debug("Address base: %pap limit %pap public 0x%llx private 0x%llx\n",
&adev->mc.aper_base, &aper_limit, &adev->gmc.aper_base, &aper_limit,
mem_info->local_mem_size_public, mem_info->local_mem_size_public,
mem_info->local_mem_size_private); mem_info->local_mem_size_private);
if (amdgpu_emu_mode == 1) {
mem_info->mem_clk_max = 100;
return;
}
if (amdgpu_sriov_vf(adev)) if (amdgpu_sriov_vf(adev))
mem_info->mem_clk_max = adev->clock.default_mclk / 100; mem_info->mem_clk_max = adev->clock.default_mclk / 100;
else else
...@@ -319,6 +329,9 @@ uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd) ...@@ -319,6 +329,9 @@ uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd)
struct amdgpu_device *adev = (struct amdgpu_device *)kgd; struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
/* the sclk is in quantas of 10kHz */ /* the sclk is in quantas of 10kHz */
if (amdgpu_emu_mode == 1)
return 100;
if (amdgpu_sriov_vf(adev)) if (amdgpu_sriov_vf(adev))
return adev->clock.default_sclk / 100; return adev->clock.default_sclk / 100;
...@@ -354,3 +367,68 @@ uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd) ...@@ -354,3 +367,68 @@ uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd)
return amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]); return amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
} }
int amdgpu_amdkfd_submit_ib(struct kgd_dev *kgd, enum kgd_engine_type engine,
uint32_t vmid, uint64_t gpu_addr,
uint32_t *ib_cmd, uint32_t ib_len)
{
struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
struct amdgpu_job *job;
struct amdgpu_ib *ib;
struct amdgpu_ring *ring;
struct dma_fence *f = NULL;
int ret;
switch (engine) {
case KGD_ENGINE_MEC1:
ring = &adev->gfx.compute_ring[0];
break;
case KGD_ENGINE_SDMA1:
ring = &adev->sdma.instance[0].ring;
break;
case KGD_ENGINE_SDMA2:
ring = &adev->sdma.instance[1].ring;
break;
default:
pr_err("Invalid engine in IB submission: %d\n", engine);
ret = -EINVAL;
goto err;
}
ret = amdgpu_job_alloc(adev, 1, &job, NULL);
if (ret)
goto err;
ib = &job->ibs[0];
memset(ib, 0, sizeof(struct amdgpu_ib));
ib->gpu_addr = gpu_addr;
ib->ptr = ib_cmd;
ib->length_dw = ib_len;
/* This works for NO_HWS. TODO: need to handle without knowing VMID */
job->vmid = vmid;
ret = amdgpu_ib_schedule(ring, 1, ib, job, &f);
if (ret) {
DRM_ERROR("amdgpu: failed to schedule IB.\n");
goto err_ib_sched;
}
ret = dma_fence_wait(f, false);
err_ib_sched:
dma_fence_put(f);
amdgpu_job_free(job);
err:
return ret;
}
bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid)
{
if (adev->kfd) {
if ((1 << vmid) & compute_vmid_bitmap)
return true;
}
return false;
}
...@@ -28,13 +28,89 @@ ...@@ -28,13 +28,89 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/mmu_context.h> #include <linux/mmu_context.h>
#include <kgd_kfd_interface.h> #include <kgd_kfd_interface.h>
#include <drm/ttm/ttm_execbuf_util.h>
#include "amdgpu_sync.h"
#include "amdgpu_vm.h"
extern const struct kgd2kfd_calls *kgd2kfd;
struct amdgpu_device; struct amdgpu_device;
struct kfd_bo_va_list {
struct list_head bo_list;
struct amdgpu_bo_va *bo_va;
void *kgd_dev;
bool is_mapped;
uint64_t va;
uint64_t pte_flags;
};
struct kgd_mem { struct kgd_mem {
struct mutex lock;
struct amdgpu_bo *bo; struct amdgpu_bo *bo;
uint64_t gpu_addr; struct list_head bo_va_list;
void *cpu_ptr; /* protected by amdkfd_process_info.lock */
struct ttm_validate_buffer validate_list;
struct ttm_validate_buffer resv_list;
uint32_t domain;
unsigned int mapped_to_gpu_memory;
uint64_t va;
uint32_t mapping_flags;
struct amdkfd_process_info *process_info;
struct amdgpu_sync sync;
bool aql_queue;
};
/* KFD Memory Eviction */
struct amdgpu_amdkfd_fence {
struct dma_fence base;
struct mm_struct *mm;
spinlock_t lock;
char timeline_name[TASK_COMM_LEN];
};
struct amdgpu_amdkfd_fence *amdgpu_amdkfd_fence_create(u64 context,
struct mm_struct *mm);
bool amdkfd_fence_check_mm(struct dma_fence *f, struct mm_struct *mm);
struct amdgpu_amdkfd_fence *to_amdgpu_amdkfd_fence(struct dma_fence *f);
struct amdkfd_process_info {
/* List head of all VMs that belong to a KFD process */
struct list_head vm_list_head;
/* List head for all KFD BOs that belong to a KFD process. */
struct list_head kfd_bo_list;
/* Lock to protect kfd_bo_list */
struct mutex lock;
/* Number of VMs */
unsigned int n_vms;
/* Eviction Fence */
struct amdgpu_amdkfd_fence *eviction_fence;
};
/* struct amdkfd_vm -
* For Memory Eviction KGD requires a mechanism to keep track of all KFD BOs
* belonging to a KFD process. All the VMs belonging to the same process point
* to the same amdkfd_process_info.
*/
struct amdkfd_vm {
/* Keep base as the first parameter for pointer compatibility between
* amdkfd_vm and amdgpu_vm.
*/
struct amdgpu_vm base;
/* List node in amdkfd_process_info.vm_list_head*/
struct list_head vm_list_node;
struct amdgpu_device *adev;
/* Points to the KFD process VM info*/
struct amdkfd_process_info *process_info;
uint64_t pd_phys_addr;
}; };
int amdgpu_amdkfd_init(void); int amdgpu_amdkfd_init(void);
...@@ -48,9 +124,15 @@ void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev); ...@@ -48,9 +124,15 @@ void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev);
void amdgpu_amdkfd_device_init(struct amdgpu_device *adev); void amdgpu_amdkfd_device_init(struct amdgpu_device *adev);
void amdgpu_amdkfd_device_fini(struct amdgpu_device *adev); void amdgpu_amdkfd_device_fini(struct amdgpu_device *adev);
int amdgpu_amdkfd_submit_ib(struct kgd_dev *kgd, enum kgd_engine_type engine,
uint32_t vmid, uint64_t gpu_addr,
uint32_t *ib_cmd, uint32_t ib_len);
struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void); struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void);
struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void); struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void);
bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid);
/* Shared API */ /* Shared API */
int alloc_gtt_mem(struct kgd_dev *kgd, size_t size, int alloc_gtt_mem(struct kgd_dev *kgd, size_t size,
void **mem_obj, uint64_t *gpu_addr, void **mem_obj, uint64_t *gpu_addr,
...@@ -79,4 +161,30 @@ uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd); ...@@ -79,4 +161,30 @@ uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd);
valid; \ valid; \
}) })
/* GPUVM API */
int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, void **vm,
void **process_info,
struct dma_fence **ef);
void amdgpu_amdkfd_gpuvm_destroy_process_vm(struct kgd_dev *kgd, void *vm);
uint32_t amdgpu_amdkfd_gpuvm_get_process_page_dir(void *vm);
int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
struct kgd_dev *kgd, uint64_t va, uint64_t size,
void *vm, struct kgd_mem **mem,
uint64_t *offset, uint32_t flags);
int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
struct kgd_dev *kgd, struct kgd_mem *mem);
int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
struct kgd_dev *kgd, struct kgd_mem *mem, void *vm);
int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
struct kgd_dev *kgd, struct kgd_mem *mem, void *vm);
int amdgpu_amdkfd_gpuvm_sync_memory(
struct kgd_dev *kgd, struct kgd_mem *mem, bool intr);
int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_dev *kgd,
struct kgd_mem *mem, void **kptr, uint64_t *size);
int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info,
struct dma_fence **ef);
void amdgpu_amdkfd_gpuvm_init_mem_limits(void);
void amdgpu_amdkfd_unreserve_system_memory_limit(struct amdgpu_bo *bo);
#endif /* AMDGPU_AMDKFD_H_INCLUDED */ #endif /* AMDGPU_AMDKFD_H_INCLUDED */
/*
* Copyright 2016-2018 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include <linux/dma-fence.h>
#include <linux/spinlock.h>
#include <linux/atomic.h>
#include <linux/stacktrace.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/sched/mm.h>
#include "amdgpu_amdkfd.h"
static const struct dma_fence_ops amdkfd_fence_ops;
static atomic_t fence_seq = ATOMIC_INIT(0);
/* Eviction Fence
* Fence helper functions to deal with KFD memory eviction.
* Big Idea - Since KFD submissions are done by user queues, a BO cannot be
* evicted unless all the user queues for that process are evicted.
*
* All the BOs in a process share an eviction fence. When process X wants
* to map VRAM memory but TTM can't find enough space, TTM will attempt to
* evict BOs from its LRU list. TTM checks if the BO is valuable to evict
* by calling ttm_bo_driver->eviction_valuable().
*
* ttm_bo_driver->eviction_valuable() - will return false if the BO belongs
* to process X. Otherwise, it will return true to indicate BO can be
* evicted by TTM.
*
* If ttm_bo_driver->eviction_valuable returns true, then TTM will continue
* the evcition process for that BO by calling ttm_bo_evict --> amdgpu_bo_move
* --> amdgpu_copy_buffer(). This sets up job in GPU scheduler.
*
* GPU Scheduler (amd_sched_main) - sets up a cb (fence_add_callback) to
* nofity when the BO is free to move. fence_add_callback --> enable_signaling
* --> amdgpu_amdkfd_fence.enable_signaling
*
* amdgpu_amdkfd_fence.enable_signaling - Start a work item that will quiesce
* user queues and signal fence. The work item will also start another delayed
* work item to restore BOs
*/
struct amdgpu_amdkfd_fence *amdgpu_amdkfd_fence_create(u64 context,
struct mm_struct *mm)
{
struct amdgpu_amdkfd_fence *fence;
fence = kzalloc(sizeof(*fence), GFP_KERNEL);
if (fence == NULL)
return NULL;
/* This reference gets released in amdkfd_fence_release */
mmgrab(mm);
fence->mm = mm;
get_task_comm(fence->timeline_name, current);
spin_lock_init(&fence->lock);
dma_fence_init(&fence->base, &amdkfd_fence_ops, &fence->lock,
context, atomic_inc_return(&fence_seq));
return fence;
}
struct amdgpu_amdkfd_fence *to_amdgpu_amdkfd_fence(struct dma_fence *f)
{
struct amdgpu_amdkfd_fence *fence;
if (!f)
return NULL;
fence = container_of(f, struct amdgpu_amdkfd_fence, base);
if (fence && f->ops == &amdkfd_fence_ops)
return fence;
return NULL;
}
static const char *amdkfd_fence_get_driver_name(struct dma_fence *f)
{
return "amdgpu_amdkfd_fence";
}
static const char *amdkfd_fence_get_timeline_name(struct dma_fence *f)
{
struct amdgpu_amdkfd_fence *fence = to_amdgpu_amdkfd_fence(f);
return fence->timeline_name;
}
/**
* amdkfd_fence_enable_signaling - This gets called when TTM wants to evict
* a KFD BO and schedules a job to move the BO.
* If fence is already signaled return true.
* If fence is not signaled schedule a evict KFD process work item.
*/
static bool amdkfd_fence_enable_signaling(struct dma_fence *f)
{
struct amdgpu_amdkfd_fence *fence = to_amdgpu_amdkfd_fence(f);
if (!fence)
return false;
if (dma_fence_is_signaled(f))
return true;
if (!kgd2kfd->schedule_evict_and_restore_process(fence->mm, f))
return true;
return false;
}
/**
* amdkfd_fence_release - callback that fence can be freed
*
* @fence: fence
*
* This function is called when the reference count becomes zero.
* Drops the mm_struct reference and RCU schedules freeing up the fence.
*/
static void amdkfd_fence_release(struct dma_fence *f)
{
struct amdgpu_amdkfd_fence *fence = to_amdgpu_amdkfd_fence(f);
/* Unconditionally signal the fence. The process is getting
* terminated.
*/
if (WARN_ON(!fence))
return; /* Not an amdgpu_amdkfd_fence */
mmdrop(fence->mm);
kfree_rcu(f, rcu);
}
/**
* amdkfd_fence_check_mm - Check if @mm is same as that of the fence @f
* if same return TRUE else return FALSE.
*
* @f: [IN] fence
* @mm: [IN] mm that needs to be verified
*/
bool amdkfd_fence_check_mm(struct dma_fence *f, struct mm_struct *mm)
{
struct amdgpu_amdkfd_fence *fence = to_amdgpu_amdkfd_fence(f);
if (!fence)
return false;
else if (fence->mm == mm)
return true;
return false;
}
static const struct dma_fence_ops amdkfd_fence_ops = {
.get_driver_name = amdkfd_fence_get_driver_name,
.get_timeline_name = amdkfd_fence_get_timeline_name,
.enable_signaling = amdkfd_fence_enable_signaling,
.signaled = NULL,
.wait = dma_fence_default_wait,
.release = amdkfd_fence_release,
};
...@@ -139,11 +139,14 @@ static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd, ...@@ -139,11 +139,14 @@ static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd,
static bool get_atc_vmid_pasid_mapping_valid(struct kgd_dev *kgd, uint8_t vmid); static bool get_atc_vmid_pasid_mapping_valid(struct kgd_dev *kgd, uint8_t vmid);
static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd, static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd,
uint8_t vmid); uint8_t vmid);
static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid);
static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type); static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type);
static void set_scratch_backing_va(struct kgd_dev *kgd, static void set_scratch_backing_va(struct kgd_dev *kgd,
uint64_t va, uint32_t vmid); uint64_t va, uint32_t vmid);
static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
uint32_t page_table_base);
static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid);
static int invalidate_tlbs_vmid(struct kgd_dev *kgd, uint16_t vmid);
/* Because of REG_GET_FIELD() being used, we put this function in the /* Because of REG_GET_FIELD() being used, we put this function in the
* asic specific file. * asic specific file.
...@@ -196,12 +199,25 @@ static const struct kfd2kgd_calls kfd2kgd = { ...@@ -196,12 +199,25 @@ static const struct kfd2kgd_calls kfd2kgd = {
.address_watch_get_offset = kgd_address_watch_get_offset, .address_watch_get_offset = kgd_address_watch_get_offset,
.get_atc_vmid_pasid_mapping_pasid = get_atc_vmid_pasid_mapping_pasid, .get_atc_vmid_pasid_mapping_pasid = get_atc_vmid_pasid_mapping_pasid,
.get_atc_vmid_pasid_mapping_valid = get_atc_vmid_pasid_mapping_valid, .get_atc_vmid_pasid_mapping_valid = get_atc_vmid_pasid_mapping_valid,
.write_vmid_invalidate_request = write_vmid_invalidate_request,
.get_fw_version = get_fw_version, .get_fw_version = get_fw_version,
.set_scratch_backing_va = set_scratch_backing_va, .set_scratch_backing_va = set_scratch_backing_va,
.get_tile_config = get_tile_config, .get_tile_config = get_tile_config,
.get_cu_info = get_cu_info, .get_cu_info = get_cu_info,
.get_vram_usage = amdgpu_amdkfd_get_vram_usage .get_vram_usage = amdgpu_amdkfd_get_vram_usage,
.create_process_vm = amdgpu_amdkfd_gpuvm_create_process_vm,
.destroy_process_vm = amdgpu_amdkfd_gpuvm_destroy_process_vm,
.get_process_page_dir = amdgpu_amdkfd_gpuvm_get_process_page_dir,
.set_vm_context_page_table_base = set_vm_context_page_table_base,
.alloc_memory_of_gpu = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu,
.free_memory_of_gpu = amdgpu_amdkfd_gpuvm_free_memory_of_gpu,
.map_memory_to_gpu = amdgpu_amdkfd_gpuvm_map_memory_to_gpu,
.unmap_memory_to_gpu = amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu,
.sync_memory = amdgpu_amdkfd_gpuvm_sync_memory,
.map_gtt_bo_to_kernel = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel,
.restore_process_bos = amdgpu_amdkfd_gpuvm_restore_process_bos,
.invalidate_tlbs = invalidate_tlbs,
.invalidate_tlbs_vmid = invalidate_tlbs_vmid,
.submit_ib = amdgpu_amdkfd_submit_ib,
}; };
struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void) struct kfd2kgd_calls *amdgpu_amdkfd_gfx_7_get_functions(void)
...@@ -787,14 +803,7 @@ static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd, ...@@ -787,14 +803,7 @@ static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd,
struct amdgpu_device *adev = (struct amdgpu_device *) kgd; struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
reg = RREG32(mmATC_VMID0_PASID_MAPPING + vmid); reg = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
return reg & ATC_VMID0_PASID_MAPPING__VALID_MASK; return reg & ATC_VMID0_PASID_MAPPING__PASID_MASK;
}
static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid)
{
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
} }
static void set_scratch_backing_va(struct kgd_dev *kgd, static void set_scratch_backing_va(struct kgd_dev *kgd,
...@@ -812,8 +821,6 @@ static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type) ...@@ -812,8 +821,6 @@ static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
struct amdgpu_device *adev = (struct amdgpu_device *) kgd; struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
const union amdgpu_firmware_header *hdr; const union amdgpu_firmware_header *hdr;
BUG_ON(kgd == NULL);
switch (type) { switch (type) {
case KGD_ENGINE_PFP: case KGD_ENGINE_PFP:
hdr = (const union amdgpu_firmware_header *) hdr = (const union amdgpu_firmware_header *)
...@@ -866,3 +873,50 @@ static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type) ...@@ -866,3 +873,50 @@ static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
return hdr->common.ucode_version; return hdr->common.ucode_version;
} }
static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
uint32_t page_table_base)
{
struct amdgpu_device *adev = get_amdgpu_device(kgd);
if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) {
pr_err("trying to set page table base for wrong VMID\n");
return;
}
WREG32(mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + vmid - 8, page_table_base);
}
static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid)
{
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
int vmid;
unsigned int tmp;
for (vmid = 0; vmid < 16; vmid++) {
if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid))
continue;
tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
if ((tmp & ATC_VMID0_PASID_MAPPING__VALID_MASK) &&
(tmp & ATC_VMID0_PASID_MAPPING__PASID_MASK) == pasid) {
WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
RREG32(mmVM_INVALIDATE_RESPONSE);
break;
}
}
return 0;
}
static int invalidate_tlbs_vmid(struct kgd_dev *kgd, uint16_t vmid)
{
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) {
pr_err("non kfd vmid\n");
return 0;
}
WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
RREG32(mmVM_INVALIDATE_RESPONSE);
return 0;
}
...@@ -81,7 +81,6 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd, ...@@ -81,7 +81,6 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd,
uint32_t queue_id); uint32_t queue_id);
static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd, static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
unsigned int utimeout); unsigned int utimeout);
static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid);
static int kgd_address_watch_disable(struct kgd_dev *kgd); static int kgd_address_watch_disable(struct kgd_dev *kgd);
static int kgd_address_watch_execute(struct kgd_dev *kgd, static int kgd_address_watch_execute(struct kgd_dev *kgd,
unsigned int watch_point_id, unsigned int watch_point_id,
...@@ -99,10 +98,13 @@ static bool get_atc_vmid_pasid_mapping_valid(struct kgd_dev *kgd, ...@@ -99,10 +98,13 @@ static bool get_atc_vmid_pasid_mapping_valid(struct kgd_dev *kgd,
uint8_t vmid); uint8_t vmid);
static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd, static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd,
uint8_t vmid); uint8_t vmid);
static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid);
static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type); static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type);
static void set_scratch_backing_va(struct kgd_dev *kgd, static void set_scratch_backing_va(struct kgd_dev *kgd,
uint64_t va, uint32_t vmid); uint64_t va, uint32_t vmid);
static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
uint32_t page_table_base);
static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid);
static int invalidate_tlbs_vmid(struct kgd_dev *kgd, uint16_t vmid);
/* Because of REG_GET_FIELD() being used, we put this function in the /* Because of REG_GET_FIELD() being used, we put this function in the
* asic specific file. * asic specific file.
...@@ -157,12 +159,25 @@ static const struct kfd2kgd_calls kfd2kgd = { ...@@ -157,12 +159,25 @@ static const struct kfd2kgd_calls kfd2kgd = {
get_atc_vmid_pasid_mapping_pasid, get_atc_vmid_pasid_mapping_pasid,
.get_atc_vmid_pasid_mapping_valid = .get_atc_vmid_pasid_mapping_valid =
get_atc_vmid_pasid_mapping_valid, get_atc_vmid_pasid_mapping_valid,
.write_vmid_invalidate_request = write_vmid_invalidate_request,
.get_fw_version = get_fw_version, .get_fw_version = get_fw_version,
.set_scratch_backing_va = set_scratch_backing_va, .set_scratch_backing_va = set_scratch_backing_va,
.get_tile_config = get_tile_config, .get_tile_config = get_tile_config,
.get_cu_info = get_cu_info, .get_cu_info = get_cu_info,
.get_vram_usage = amdgpu_amdkfd_get_vram_usage .get_vram_usage = amdgpu_amdkfd_get_vram_usage,
.create_process_vm = amdgpu_amdkfd_gpuvm_create_process_vm,
.destroy_process_vm = amdgpu_amdkfd_gpuvm_destroy_process_vm,
.get_process_page_dir = amdgpu_amdkfd_gpuvm_get_process_page_dir,
.set_vm_context_page_table_base = set_vm_context_page_table_base,
.alloc_memory_of_gpu = amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu,
.free_memory_of_gpu = amdgpu_amdkfd_gpuvm_free_memory_of_gpu,
.map_memory_to_gpu = amdgpu_amdkfd_gpuvm_map_memory_to_gpu,
.unmap_memory_to_gpu = amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu,
.sync_memory = amdgpu_amdkfd_gpuvm_sync_memory,
.map_gtt_bo_to_kernel = amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel,
.restore_process_bos = amdgpu_amdkfd_gpuvm_restore_process_bos,
.invalidate_tlbs = invalidate_tlbs,
.invalidate_tlbs_vmid = invalidate_tlbs_vmid,
.submit_ib = amdgpu_amdkfd_submit_ib,
}; };
struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void) struct kfd2kgd_calls *amdgpu_amdkfd_gfx_8_0_get_functions(void)
...@@ -704,14 +719,7 @@ static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd, ...@@ -704,14 +719,7 @@ static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd,
struct amdgpu_device *adev = (struct amdgpu_device *) kgd; struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
reg = RREG32(mmATC_VMID0_PASID_MAPPING + vmid); reg = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
return reg & ATC_VMID0_PASID_MAPPING__VALID_MASK; return reg & ATC_VMID0_PASID_MAPPING__PASID_MASK;
}
static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid)
{
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
} }
static int kgd_address_watch_disable(struct kgd_dev *kgd) static int kgd_address_watch_disable(struct kgd_dev *kgd)
...@@ -775,8 +783,6 @@ static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type) ...@@ -775,8 +783,6 @@ static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
struct amdgpu_device *adev = (struct amdgpu_device *) kgd; struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
const union amdgpu_firmware_header *hdr; const union amdgpu_firmware_header *hdr;
BUG_ON(kgd == NULL);
switch (type) { switch (type) {
case KGD_ENGINE_PFP: case KGD_ENGINE_PFP:
hdr = (const union amdgpu_firmware_header *) hdr = (const union amdgpu_firmware_header *)
...@@ -828,3 +834,51 @@ static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type) ...@@ -828,3 +834,51 @@ static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type)
/* Only 12 bit in use*/ /* Only 12 bit in use*/
return hdr->common.ucode_version; return hdr->common.ucode_version;
} }
static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid,
uint32_t page_table_base)
{
struct amdgpu_device *adev = get_amdgpu_device(kgd);
if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) {
pr_err("trying to set page table base for wrong VMID\n");
return;
}
WREG32(mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + vmid - 8, page_table_base);
}
static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid)
{
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
int vmid;
unsigned int tmp;
for (vmid = 0; vmid < 16; vmid++) {
if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid))
continue;
tmp = RREG32(mmATC_VMID0_PASID_MAPPING + vmid);
if ((tmp & ATC_VMID0_PASID_MAPPING__VALID_MASK) &&
(tmp & ATC_VMID0_PASID_MAPPING__PASID_MASK) == pasid) {
WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
RREG32(mmVM_INVALIDATE_RESPONSE);
break;
}
}
return 0;
}
static int invalidate_tlbs_vmid(struct kgd_dev *kgd, uint16_t vmid)
{
struct amdgpu_device *adev = (struct amdgpu_device *) kgd;
if (!amdgpu_amdkfd_is_kfd_vmid(adev, vmid)) {
pr_err("non kfd vmid %d\n", vmid);
return -EINVAL;
}
WREG32(mmVM_INVALIDATE_REQUEST, 1 << vmid);
RREG32(mmVM_INVALIDATE_RESPONSE);
return 0;
}
此差异已折叠。
...@@ -114,6 +114,9 @@ union igp_info { ...@@ -114,6 +114,9 @@ union igp_info {
struct atom_integrated_system_info_v1_11 v11; struct atom_integrated_system_info_v1_11 v11;
}; };
union umc_info {
struct atom_umc_info_v3_1 v31;
};
/* /*
* Return vram width from integrated system info table, if available, * Return vram width from integrated system info table, if available,
* or 0 if not. * or 0 if not.
...@@ -143,6 +146,94 @@ int amdgpu_atomfirmware_get_vram_width(struct amdgpu_device *adev) ...@@ -143,6 +146,94 @@ int amdgpu_atomfirmware_get_vram_width(struct amdgpu_device *adev)
return 0; return 0;
} }
static int convert_atom_mem_type_to_vram_type (struct amdgpu_device *adev,
int atom_mem_type)
{
int vram_type;
if (adev->flags & AMD_IS_APU) {
switch (atom_mem_type) {
case Ddr2MemType:
case LpDdr2MemType:
vram_type = AMDGPU_VRAM_TYPE_DDR2;
break;
case Ddr3MemType:
case LpDdr3MemType:
vram_type = AMDGPU_VRAM_TYPE_DDR3;
break;
case Ddr4MemType:
case LpDdr4MemType:
vram_type = AMDGPU_VRAM_TYPE_DDR4;
break;
default:
vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
break;
}
} else {
switch (atom_mem_type) {
case ATOM_DGPU_VRAM_TYPE_GDDR5:
vram_type = AMDGPU_VRAM_TYPE_GDDR5;
break;
case ATOM_DGPU_VRAM_TYPE_HBM:
vram_type = AMDGPU_VRAM_TYPE_HBM;
break;
default:
vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
break;
}
}
return vram_type;
}
/*
* Return vram type from either integrated system info table
* or umc info table, if available, or 0 (TYPE_UNKNOWN) if not
*/
int amdgpu_atomfirmware_get_vram_type(struct amdgpu_device *adev)
{
struct amdgpu_mode_info *mode_info = &adev->mode_info;
int index;
u16 data_offset, size;
union igp_info *igp_info;
union umc_info *umc_info;
u8 frev, crev;
u8 mem_type;
if (adev->flags & AMD_IS_APU)
index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
integratedsysteminfo);
else
index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
umc_info);
if (amdgpu_atom_parse_data_header(mode_info->atom_context,
index, &size,
&frev, &crev, &data_offset)) {
if (adev->flags & AMD_IS_APU) {
igp_info = (union igp_info *)
(mode_info->atom_context->bios + data_offset);
switch (crev) {
case 11:
mem_type = igp_info->v11.memorytype;
return convert_atom_mem_type_to_vram_type(adev, mem_type);
default:
return 0;
}
} else {
umc_info = (union umc_info *)
(mode_info->atom_context->bios + data_offset);
switch (crev) {
case 1:
mem_type = umc_info->v31.vram_type;
return convert_atom_mem_type_to_vram_type(adev, mem_type);
default:
return 0;
}
}
}
return 0;
}
union firmware_info { union firmware_info {
struct atom_firmware_info_v3_1 v31; struct atom_firmware_info_v3_1 v31;
}; };
...@@ -151,10 +242,6 @@ union smu_info { ...@@ -151,10 +242,6 @@ union smu_info {
struct atom_smu_info_v3_1 v31; struct atom_smu_info_v3_1 v31;
}; };
union umc_info {
struct atom_umc_info_v3_1 v31;
};
int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev) int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev)
{ {
struct amdgpu_mode_info *mode_info = &adev->mode_info; struct amdgpu_mode_info *mode_info = &adev->mode_info;
......
...@@ -28,6 +28,7 @@ bool amdgpu_atomfirmware_gpu_supports_virtualization(struct amdgpu_device *adev) ...@@ -28,6 +28,7 @@ bool amdgpu_atomfirmware_gpu_supports_virtualization(struct amdgpu_device *adev)
void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev); void amdgpu_atomfirmware_scratch_regs_init(struct amdgpu_device *adev);
int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev); int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev);
int amdgpu_atomfirmware_get_vram_width(struct amdgpu_device *adev); int amdgpu_atomfirmware_get_vram_width(struct amdgpu_device *adev);
int amdgpu_atomfirmware_get_vram_type(struct amdgpu_device *adev);
int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev); int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev);
#endif #endif
...@@ -568,6 +568,7 @@ static const struct amdgpu_px_quirk amdgpu_px_quirk_list[] = { ...@@ -568,6 +568,7 @@ static const struct amdgpu_px_quirk amdgpu_px_quirk_list[] = {
/* HG _PR3 doesn't seem to work on this A+A weston board */ /* HG _PR3 doesn't seem to work on this A+A weston board */
{ 0x1002, 0x6900, 0x1002, 0x0124, AMDGPU_PX_QUIRK_FORCE_ATPX }, { 0x1002, 0x6900, 0x1002, 0x0124, AMDGPU_PX_QUIRK_FORCE_ATPX },
{ 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX }, { 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX },
{ 0x1002, 0x6900, 0x1028, 0x0813, AMDGPU_PX_QUIRK_FORCE_ATPX },
{ 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 },
}; };
......
...@@ -80,8 +80,8 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size, ...@@ -80,8 +80,8 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size,
int time; int time;
n = AMDGPU_BENCHMARK_ITERATIONS; n = AMDGPU_BENCHMARK_ITERATIONS;
r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, sdomain, 0, NULL, r = amdgpu_bo_create(adev, size, PAGE_SIZE,sdomain, 0,
NULL, 0, &sobj); ttm_bo_type_kernel, NULL, &sobj);
if (r) { if (r) {
goto out_cleanup; goto out_cleanup;
} }
...@@ -93,8 +93,8 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size, ...@@ -93,8 +93,8 @@ static void amdgpu_benchmark_move(struct amdgpu_device *adev, unsigned size,
if (r) { if (r) {
goto out_cleanup; goto out_cleanup;
} }
r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, ddomain, 0, NULL, r = amdgpu_bo_create(adev, size, PAGE_SIZE, ddomain, 0,
NULL, 0, &dobj); ttm_bo_type_kernel, NULL, &dobj);
if (r) { if (r) {
goto out_cleanup; goto out_cleanup;
} }
......
...@@ -233,8 +233,10 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list, ...@@ -233,8 +233,10 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list,
for (i = 0; i < list->num_entries; i++) { for (i = 0; i < list->num_entries; i++) {
unsigned priority = list->array[i].priority; unsigned priority = list->array[i].priority;
list_add_tail(&list->array[i].tv.head, if (!list->array[i].robj->parent)
&bucket[priority]); list_add_tail(&list->array[i].tv.head,
&bucket[priority]);
list->array[i].user_pages = NULL; list->array[i].user_pages = NULL;
} }
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/acpi.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <drm/amdgpu_drm.h> #include <drm/amdgpu_drm.h>
...@@ -42,152 +41,6 @@ struct amdgpu_cgs_device { ...@@ -42,152 +41,6 @@ struct amdgpu_cgs_device {
struct amdgpu_device *adev = \ struct amdgpu_device *adev = \
((struct amdgpu_cgs_device *)cgs_device)->adev ((struct amdgpu_cgs_device *)cgs_device)->adev
static void *amdgpu_cgs_register_pp_handle(struct cgs_device *cgs_device,
int (*call_back_func)(struct amd_pp_init *, void **))
{
CGS_FUNC_ADEV;
struct amd_pp_init pp_init;
struct amd_powerplay *amd_pp;
if (call_back_func == NULL)
return NULL;
amd_pp = &(adev->powerplay);
pp_init.chip_family = adev->family;
pp_init.chip_id = adev->asic_type;
pp_init.pm_en = (amdgpu_dpm != 0 && !amdgpu_sriov_vf(adev)) ? true : false;
pp_init.feature_mask = amdgpu_pp_feature_mask;
pp_init.device = cgs_device;
if (call_back_func(&pp_init, &(amd_pp->pp_handle)))
return NULL;
return adev->powerplay.pp_handle;
}
static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device,
enum cgs_gpu_mem_type type,
uint64_t size, uint64_t align,
cgs_handle_t *handle)
{
CGS_FUNC_ADEV;
uint16_t flags = 0;
int ret = 0;
uint32_t domain = 0;
struct amdgpu_bo *obj;
/* fail if the alignment is not a power of 2 */
if (((align != 1) && (align & (align - 1)))
|| size == 0 || align == 0)
return -EINVAL;
switch(type) {
case CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB:
case CGS_GPU_MEM_TYPE__VISIBLE_FB:
flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
domain = AMDGPU_GEM_DOMAIN_VRAM;
break;
case CGS_GPU_MEM_TYPE__INVISIBLE_CONTIG_FB:
case CGS_GPU_MEM_TYPE__INVISIBLE_FB:
flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
domain = AMDGPU_GEM_DOMAIN_VRAM;
break;
case CGS_GPU_MEM_TYPE__GART_CACHEABLE:
domain = AMDGPU_GEM_DOMAIN_GTT;
break;
case CGS_GPU_MEM_TYPE__GART_WRITECOMBINE:
flags = AMDGPU_GEM_CREATE_CPU_GTT_USWC;
domain = AMDGPU_GEM_DOMAIN_GTT;
break;
default:
return -EINVAL;
}
*handle = 0;
ret = amdgpu_bo_create(adev, size, align, true, domain, flags,
NULL, NULL, 0, &obj);
if (ret) {
DRM_ERROR("(%d) bo create failed\n", ret);
return ret;
}
*handle = (cgs_handle_t)obj;
return ret;
}
static int amdgpu_cgs_free_gpu_mem(struct cgs_device *cgs_device, cgs_handle_t handle)
{
struct amdgpu_bo *obj = (struct amdgpu_bo *)handle;
if (obj) {
int r = amdgpu_bo_reserve(obj, true);
if (likely(r == 0)) {
amdgpu_bo_kunmap(obj);
amdgpu_bo_unpin(obj);
amdgpu_bo_unreserve(obj);
}
amdgpu_bo_unref(&obj);
}
return 0;
}
static int amdgpu_cgs_gmap_gpu_mem(struct cgs_device *cgs_device, cgs_handle_t handle,
uint64_t *mcaddr)
{
int r;
struct amdgpu_bo *obj = (struct amdgpu_bo *)handle;
WARN_ON_ONCE(obj->placement.num_placement > 1);
r = amdgpu_bo_reserve(obj, true);
if (unlikely(r != 0))
return r;
r = amdgpu_bo_pin(obj, obj->preferred_domains, mcaddr);
amdgpu_bo_unreserve(obj);
return r;
}
static int amdgpu_cgs_gunmap_gpu_mem(struct cgs_device *cgs_device, cgs_handle_t handle)
{
int r;
struct amdgpu_bo *obj = (struct amdgpu_bo *)handle;
r = amdgpu_bo_reserve(obj, true);
if (unlikely(r != 0))
return r;
r = amdgpu_bo_unpin(obj);
amdgpu_bo_unreserve(obj);
return r;
}
static int amdgpu_cgs_kmap_gpu_mem(struct cgs_device *cgs_device, cgs_handle_t handle,
void **map)
{
int r;
struct amdgpu_bo *obj = (struct amdgpu_bo *)handle;
r = amdgpu_bo_reserve(obj, true);
if (unlikely(r != 0))
return r;
r = amdgpu_bo_kmap(obj, map);
amdgpu_bo_unreserve(obj);
return r;
}
static int amdgpu_cgs_kunmap_gpu_mem(struct cgs_device *cgs_device, cgs_handle_t handle)
{
int r;
struct amdgpu_bo *obj = (struct amdgpu_bo *)handle;
r = amdgpu_bo_reserve(obj, true);
if (unlikely(r != 0))
return r;
amdgpu_bo_kunmap(obj);
amdgpu_bo_unreserve(obj);
return r;
}
static uint32_t amdgpu_cgs_read_register(struct cgs_device *cgs_device, unsigned offset) static uint32_t amdgpu_cgs_read_register(struct cgs_device *cgs_device, unsigned offset)
{ {
...@@ -801,11 +654,6 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, ...@@ -801,11 +654,6 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
else else
strcpy(fw_name, "amdgpu/vega10_smc.bin"); strcpy(fw_name, "amdgpu/vega10_smc.bin");
break; break;
case CHIP_CARRIZO:
case CHIP_STONEY:
case CHIP_RAVEN:
adev->pm.fw_version = info->version;
return 0;
default: default:
DRM_ERROR("SMC firmware not supported\n"); DRM_ERROR("SMC firmware not supported\n");
return -EINVAL; return -EINVAL;
...@@ -857,61 +705,6 @@ static int amdgpu_cgs_is_virtualization_enabled(void *cgs_device) ...@@ -857,61 +705,6 @@ static int amdgpu_cgs_is_virtualization_enabled(void *cgs_device)
return amdgpu_sriov_vf(adev); return amdgpu_sriov_vf(adev);
} }
static int amdgpu_cgs_query_system_info(struct cgs_device *cgs_device,
struct cgs_system_info *sys_info)
{
CGS_FUNC_ADEV;
if (NULL == sys_info)
return -ENODEV;
if (sizeof(struct cgs_system_info) != sys_info->size)
return -ENODEV;
switch (sys_info->info_id) {
case CGS_SYSTEM_INFO_ADAPTER_BDF_ID:
sys_info->value = adev->pdev->devfn | (adev->pdev->bus->number << 8);
break;
case CGS_SYSTEM_INFO_PCIE_GEN_INFO:
sys_info->value = adev->pm.pcie_gen_mask;
break;
case CGS_SYSTEM_INFO_PCIE_MLW:
sys_info->value = adev->pm.pcie_mlw_mask;
break;
case CGS_SYSTEM_INFO_PCIE_DEV:
sys_info->value = adev->pdev->device;
break;
case CGS_SYSTEM_INFO_PCIE_REV:
sys_info->value = adev->pdev->revision;
break;
case CGS_SYSTEM_INFO_CG_FLAGS:
sys_info->value = adev->cg_flags;
break;
case CGS_SYSTEM_INFO_PG_FLAGS:
sys_info->value = adev->pg_flags;
break;
case CGS_SYSTEM_INFO_GFX_CU_INFO:
sys_info->value = adev->gfx.cu_info.number;
break;
case CGS_SYSTEM_INFO_GFX_SE_INFO:
sys_info->value = adev->gfx.config.max_shader_engines;
break;
case CGS_SYSTEM_INFO_PCIE_SUB_SYS_ID:
sys_info->value = adev->pdev->subsystem_device;
break;
case CGS_SYSTEM_INFO_PCIE_SUB_SYS_VENDOR_ID:
sys_info->value = adev->pdev->subsystem_vendor;
break;
case CGS_SYSTEM_INFO_PCIE_BUS_DEVFN:
sys_info->value = adev->pdev->devfn;
break;
default:
return -ENODEV;
}
return 0;
}
static int amdgpu_cgs_get_active_displays_info(struct cgs_device *cgs_device, static int amdgpu_cgs_get_active_displays_info(struct cgs_device *cgs_device,
struct cgs_display_info *info) struct cgs_display_info *info)
{ {
...@@ -953,6 +746,11 @@ static int amdgpu_cgs_get_active_displays_info(struct cgs_device *cgs_device, ...@@ -953,6 +746,11 @@ static int amdgpu_cgs_get_active_displays_info(struct cgs_device *cgs_device,
(amdgpu_crtc->v_border * 2); (amdgpu_crtc->v_border * 2);
mode_info->vblank_time_us = vblank_lines * line_time_us; mode_info->vblank_time_us = vblank_lines * line_time_us;
mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode); mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
/* we have issues with mclk switching with refresh rates
* over 120 hz on the non-DC code.
*/
if (mode_info->refresh_rate > 120)
mode_info->vblank_time_us = 0;
mode_info = NULL; mode_info = NULL;
} }
} }
...@@ -977,223 +775,7 @@ static int amdgpu_cgs_notify_dpm_enabled(struct cgs_device *cgs_device, bool ena ...@@ -977,223 +775,7 @@ static int amdgpu_cgs_notify_dpm_enabled(struct cgs_device *cgs_device, bool ena
return 0; return 0;
} }
/** \brief evaluate acpi namespace object, handle or pathname must be valid
* \param cgs_device
* \param info input/output arguments for the control method
* \return status
*/
#if defined(CONFIG_ACPI)
static int amdgpu_cgs_acpi_eval_object(struct cgs_device *cgs_device,
struct cgs_acpi_method_info *info)
{
CGS_FUNC_ADEV;
acpi_handle handle;
struct acpi_object_list input;
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *params, *obj;
uint8_t name[5] = {'\0'};
struct cgs_acpi_method_argument *argument;
uint32_t i, count;
acpi_status status;
int result;
handle = ACPI_HANDLE(&adev->pdev->dev);
if (!handle)
return -ENODEV;
memset(&input, 0, sizeof(struct acpi_object_list));
/* validate input info */
if (info->size != sizeof(struct cgs_acpi_method_info))
return -EINVAL;
input.count = info->input_count;
if (info->input_count > 0) {
if (info->pinput_argument == NULL)
return -EINVAL;
argument = info->pinput_argument;
for (i = 0; i < info->input_count; i++) {
if (((argument->type == ACPI_TYPE_STRING) ||
(argument->type == ACPI_TYPE_BUFFER)) &&
(argument->pointer == NULL))
return -EINVAL;
argument++;
}
}
if (info->output_count > 0) {
if (info->poutput_argument == NULL)
return -EINVAL;
argument = info->poutput_argument;
for (i = 0; i < info->output_count; i++) {
if (((argument->type == ACPI_TYPE_STRING) ||
(argument->type == ACPI_TYPE_BUFFER))
&& (argument->pointer == NULL))
return -EINVAL;
argument++;
}
}
/* The path name passed to acpi_evaluate_object should be null terminated */
if ((info->field & CGS_ACPI_FIELD_METHOD_NAME) != 0) {
strncpy(name, (char *)&(info->name), sizeof(uint32_t));
name[4] = '\0';
}
/* parse input parameters */
if (input.count > 0) {
input.pointer = params =
kzalloc(sizeof(union acpi_object) * input.count, GFP_KERNEL);
if (params == NULL)
return -EINVAL;
argument = info->pinput_argument;
for (i = 0; i < input.count; i++) {
params->type = argument->type;
switch (params->type) {
case ACPI_TYPE_INTEGER:
params->integer.value = argument->value;
break;
case ACPI_TYPE_STRING:
params->string.length = argument->data_length;
params->string.pointer = argument->pointer;
break;
case ACPI_TYPE_BUFFER:
params->buffer.length = argument->data_length;
params->buffer.pointer = argument->pointer;
break;
default:
break;
}
params++;
argument++;
}
}
/* parse output info */
count = info->output_count;
argument = info->poutput_argument;
/* evaluate the acpi method */
status = acpi_evaluate_object(handle, name, &input, &output);
if (ACPI_FAILURE(status)) {
result = -EIO;
goto free_input;
}
/* return the output info */
obj = output.pointer;
if (count > 1) {
if ((obj->type != ACPI_TYPE_PACKAGE) ||
(obj->package.count != count)) {
result = -EIO;
goto free_obj;
}
params = obj->package.elements;
} else
params = obj;
if (params == NULL) {
result = -EIO;
goto free_obj;
}
for (i = 0; i < count; i++) {
if (argument->type != params->type) {
result = -EIO;
goto free_obj;
}
switch (params->type) {
case ACPI_TYPE_INTEGER:
argument->value = params->integer.value;
break;
case ACPI_TYPE_STRING:
if ((params->string.length != argument->data_length) ||
(params->string.pointer == NULL)) {
result = -EIO;
goto free_obj;
}
strncpy(argument->pointer,
params->string.pointer,
params->string.length);
break;
case ACPI_TYPE_BUFFER:
if (params->buffer.pointer == NULL) {
result = -EIO;
goto free_obj;
}
memcpy(argument->pointer,
params->buffer.pointer,
argument->data_length);
break;
default:
break;
}
argument++;
params++;
}
result = 0;
free_obj:
kfree(obj);
free_input:
kfree((void *)input.pointer);
return result;
}
#else
static int amdgpu_cgs_acpi_eval_object(struct cgs_device *cgs_device,
struct cgs_acpi_method_info *info)
{
return -EIO;
}
#endif
static int amdgpu_cgs_call_acpi_method(struct cgs_device *cgs_device,
uint32_t acpi_method,
uint32_t acpi_function,
void *pinput, void *poutput,
uint32_t output_count,
uint32_t input_size,
uint32_t output_size)
{
struct cgs_acpi_method_argument acpi_input[2] = { {0}, {0} };
struct cgs_acpi_method_argument acpi_output = {0};
struct cgs_acpi_method_info info = {0};
acpi_input[0].type = CGS_ACPI_TYPE_INTEGER;
acpi_input[0].data_length = sizeof(uint32_t);
acpi_input[0].value = acpi_function;
acpi_input[1].type = CGS_ACPI_TYPE_BUFFER;
acpi_input[1].data_length = input_size;
acpi_input[1].pointer = pinput;
acpi_output.type = CGS_ACPI_TYPE_BUFFER;
acpi_output.data_length = output_size;
acpi_output.pointer = poutput;
info.size = sizeof(struct cgs_acpi_method_info);
info.field = CGS_ACPI_FIELD_METHOD_NAME | CGS_ACPI_FIELD_INPUT_ARGUMENT_COUNT;
info.input_count = 2;
info.name = acpi_method;
info.pinput_argument = acpi_input;
info.output_count = output_count;
info.poutput_argument = &acpi_output;
return amdgpu_cgs_acpi_eval_object(cgs_device, &info);
}
static const struct cgs_ops amdgpu_cgs_ops = { static const struct cgs_ops amdgpu_cgs_ops = {
.alloc_gpu_mem = amdgpu_cgs_alloc_gpu_mem,
.free_gpu_mem = amdgpu_cgs_free_gpu_mem,
.gmap_gpu_mem = amdgpu_cgs_gmap_gpu_mem,
.gunmap_gpu_mem = amdgpu_cgs_gunmap_gpu_mem,
.kmap_gpu_mem = amdgpu_cgs_kmap_gpu_mem,
.kunmap_gpu_mem = amdgpu_cgs_kunmap_gpu_mem,
.read_register = amdgpu_cgs_read_register, .read_register = amdgpu_cgs_read_register,
.write_register = amdgpu_cgs_write_register, .write_register = amdgpu_cgs_write_register,
.read_ind_register = amdgpu_cgs_read_ind_register, .read_ind_register = amdgpu_cgs_read_ind_register,
...@@ -1208,12 +790,9 @@ static const struct cgs_ops amdgpu_cgs_ops = { ...@@ -1208,12 +790,9 @@ static const struct cgs_ops amdgpu_cgs_ops = {
.set_clockgating_state = amdgpu_cgs_set_clockgating_state, .set_clockgating_state = amdgpu_cgs_set_clockgating_state,
.get_active_displays_info = amdgpu_cgs_get_active_displays_info, .get_active_displays_info = amdgpu_cgs_get_active_displays_info,
.notify_dpm_enabled = amdgpu_cgs_notify_dpm_enabled, .notify_dpm_enabled = amdgpu_cgs_notify_dpm_enabled,
.call_acpi_method = amdgpu_cgs_call_acpi_method,
.query_system_info = amdgpu_cgs_query_system_info,
.is_virtualization_enabled = amdgpu_cgs_is_virtualization_enabled, .is_virtualization_enabled = amdgpu_cgs_is_virtualization_enabled,
.enter_safe_mode = amdgpu_cgs_enter_safe_mode, .enter_safe_mode = amdgpu_cgs_enter_safe_mode,
.lock_grbm_idx = amdgpu_cgs_lock_grbm_idx, .lock_grbm_idx = amdgpu_cgs_lock_grbm_idx,
.register_pp_handle = amdgpu_cgs_register_pp_handle,
}; };
static const struct cgs_os_ops amdgpu_cgs_os_ops = { static const struct cgs_os_ops amdgpu_cgs_os_ops = {
......
...@@ -69,25 +69,18 @@ void amdgpu_connector_hotplug(struct drm_connector *connector) ...@@ -69,25 +69,18 @@ void amdgpu_connector_hotplug(struct drm_connector *connector)
/* don't do anything if sink is not display port, i.e., /* don't do anything if sink is not display port, i.e.,
* passive dp->(dvi|hdmi) adaptor * passive dp->(dvi|hdmi) adaptor
*/ */
if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT &&
int saved_dpms = connector->dpms; amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd) &&
/* Only turn off the display if it's physically disconnected */ amdgpu_atombios_dp_needs_link_train(amdgpu_connector)) {
if (!amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd)) { /* Don't start link training before we have the DPCD */
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); if (amdgpu_atombios_dp_get_dpcd(amdgpu_connector))
} else if (amdgpu_atombios_dp_needs_link_train(amdgpu_connector)) { return;
/* Don't try to start link training before we
* have the dpcd */ /* Turn the connector off and back on immediately, which
if (amdgpu_atombios_dp_get_dpcd(amdgpu_connector)) * will trigger link training
return; */
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
/* set it to OFF so that drm_helper_connector_dpms() drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
* won't return immediately since the current state
* is ON at this point.
*/
connector->dpms = DRM_MODE_DPMS_OFF;
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
}
connector->dpms = saved_dpms;
} }
} }
} }
...@@ -877,7 +870,7 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force) ...@@ -877,7 +870,7 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
ret = connector_status_disconnected; ret = connector_status_disconnected;
if (amdgpu_connector->ddc_bus) if (amdgpu_connector->ddc_bus)
dret = amdgpu_ddc_probe(amdgpu_connector, false); dret = amdgpu_display_ddc_probe(amdgpu_connector, false);
if (dret) { if (dret) {
amdgpu_connector->detected_by_load = false; amdgpu_connector->detected_by_load = false;
amdgpu_connector_free_edid(connector); amdgpu_connector_free_edid(connector);
...@@ -998,7 +991,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force) ...@@ -998,7 +991,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
} }
if (amdgpu_connector->ddc_bus) if (amdgpu_connector->ddc_bus)
dret = amdgpu_ddc_probe(amdgpu_connector, false); dret = amdgpu_display_ddc_probe(amdgpu_connector, false);
if (dret) { if (dret) {
amdgpu_connector->detected_by_load = false; amdgpu_connector->detected_by_load = false;
amdgpu_connector_free_edid(connector); amdgpu_connector_free_edid(connector);
...@@ -1401,7 +1394,8 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force) ...@@ -1401,7 +1394,8 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)
/* setup ddc on the bridge */ /* setup ddc on the bridge */
amdgpu_atombios_encoder_setup_ext_encoder_ddc(encoder); amdgpu_atombios_encoder_setup_ext_encoder_ddc(encoder);
/* bridge chips are always aux */ /* bridge chips are always aux */
if (amdgpu_ddc_probe(amdgpu_connector, true)) /* try DDC */ /* try DDC */
if (amdgpu_display_ddc_probe(amdgpu_connector, true))
ret = connector_status_connected; ret = connector_status_connected;
else if (amdgpu_connector->dac_load_detect) { /* try load detection */ else if (amdgpu_connector->dac_load_detect) { /* try load detection */
const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
...@@ -1421,7 +1415,8 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force) ...@@ -1421,7 +1415,8 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)
ret = connector_status_connected; ret = connector_status_connected;
} else { } else {
/* try non-aux ddc (DP to DVI/HDMI/etc. adapter) */ /* try non-aux ddc (DP to DVI/HDMI/etc. adapter) */
if (amdgpu_ddc_probe(amdgpu_connector, false)) if (amdgpu_display_ddc_probe(amdgpu_connector,
false))
ret = connector_status_connected; ret = connector_status_connected;
} }
} }
......
...@@ -257,7 +257,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev, ...@@ -257,7 +257,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev,
return; return;
} }
total_vram = adev->mc.real_vram_size - adev->vram_pin_size; total_vram = adev->gmc.real_vram_size - adev->vram_pin_size;
used_vram = amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]); used_vram = amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
free_vram = used_vram >= total_vram ? 0 : total_vram - used_vram; free_vram = used_vram >= total_vram ? 0 : total_vram - used_vram;
...@@ -302,8 +302,8 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev, ...@@ -302,8 +302,8 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev,
*max_bytes = us_to_bytes(adev, adev->mm_stats.accum_us); *max_bytes = us_to_bytes(adev, adev->mm_stats.accum_us);
/* Do the same for visible VRAM if half of it is free */ /* Do the same for visible VRAM if half of it is free */
if (adev->mc.visible_vram_size < adev->mc.real_vram_size) { if (adev->gmc.visible_vram_size < adev->gmc.real_vram_size) {
u64 total_vis_vram = adev->mc.visible_vram_size; u64 total_vis_vram = adev->gmc.visible_vram_size;
u64 used_vis_vram = u64 used_vis_vram =
amdgpu_vram_mgr_vis_usage(&adev->mman.bdev.man[TTM_PL_VRAM]); amdgpu_vram_mgr_vis_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);
...@@ -346,8 +346,8 @@ static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p, ...@@ -346,8 +346,8 @@ static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p,
struct ttm_operation_ctx ctx = { struct ttm_operation_ctx ctx = {
.interruptible = true, .interruptible = true,
.no_wait_gpu = false, .no_wait_gpu = false,
.allow_reserved_eviction = false, .resv = bo->tbo.resv,
.resv = bo->tbo.resv .flags = 0
}; };
uint32_t domain; uint32_t domain;
int r; int r;
...@@ -359,7 +359,7 @@ static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p, ...@@ -359,7 +359,7 @@ static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p,
* to move it. Don't move anything if the threshold is zero. * to move it. Don't move anything if the threshold is zero.
*/ */
if (p->bytes_moved < p->bytes_moved_threshold) { if (p->bytes_moved < p->bytes_moved_threshold) {
if (adev->mc.visible_vram_size < adev->mc.real_vram_size && if (adev->gmc.visible_vram_size < adev->gmc.real_vram_size &&
(bo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)) { (bo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)) {
/* And don't move a CPU_ACCESS_REQUIRED BO to limited /* And don't move a CPU_ACCESS_REQUIRED BO to limited
* visible VRAM if we've depleted our allowance to do * visible VRAM if we've depleted our allowance to do
...@@ -381,9 +381,9 @@ static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p, ...@@ -381,9 +381,9 @@ static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p,
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
p->bytes_moved += ctx.bytes_moved; p->bytes_moved += ctx.bytes_moved;
if (adev->mc.visible_vram_size < adev->mc.real_vram_size && if (adev->gmc.visible_vram_size < adev->gmc.real_vram_size &&
bo->tbo.mem.mem_type == TTM_PL_VRAM && bo->tbo.mem.mem_type == TTM_PL_VRAM &&
bo->tbo.mem.start < adev->mc.visible_vram_size >> PAGE_SHIFT) bo->tbo.mem.start < adev->gmc.visible_vram_size >> PAGE_SHIFT)
p->bytes_moved_vis += ctx.bytes_moved; p->bytes_moved_vis += ctx.bytes_moved;
if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) { if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) {
...@@ -437,9 +437,9 @@ static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p, ...@@ -437,9 +437,9 @@ static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p,
/* Good we can try to move this BO somewhere else */ /* Good we can try to move this BO somewhere else */
amdgpu_ttm_placement_from_domain(bo, other); amdgpu_ttm_placement_from_domain(bo, other);
update_bytes_moved_vis = update_bytes_moved_vis =
adev->mc.visible_vram_size < adev->mc.real_vram_size && adev->gmc.visible_vram_size < adev->gmc.real_vram_size &&
bo->tbo.mem.mem_type == TTM_PL_VRAM && bo->tbo.mem.mem_type == TTM_PL_VRAM &&
bo->tbo.mem.start < adev->mc.visible_vram_size >> PAGE_SHIFT; bo->tbo.mem.start < adev->gmc.visible_vram_size >> PAGE_SHIFT;
initial_bytes_moved = atomic64_read(&adev->num_bytes_moved); initial_bytes_moved = atomic64_read(&adev->num_bytes_moved);
r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
bytes_moved = atomic64_read(&adev->num_bytes_moved) - bytes_moved = atomic64_read(&adev->num_bytes_moved) -
...@@ -542,7 +542,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, ...@@ -542,7 +542,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
INIT_LIST_HEAD(&duplicates); INIT_LIST_HEAD(&duplicates);
amdgpu_vm_get_pd_bo(&fpriv->vm, &p->validated, &p->vm_pd); amdgpu_vm_get_pd_bo(&fpriv->vm, &p->validated, &p->vm_pd);
if (p->uf_entry.robj) if (p->uf_entry.robj && !p->uf_entry.robj->parent)
list_add(&p->uf_entry.tv.head, &p->validated); list_add(&p->uf_entry.tv.head, &p->validated);
while (1) { while (1) {
......
...@@ -767,10 +767,21 @@ static int amdgpu_debugfs_evict_vram(struct seq_file *m, void *data) ...@@ -767,10 +767,21 @@ static int amdgpu_debugfs_evict_vram(struct seq_file *m, void *data)
return 0; return 0;
} }
static int amdgpu_debugfs_evict_gtt(struct seq_file *m, void *data)
{
struct drm_info_node *node = (struct drm_info_node *)m->private;
struct drm_device *dev = node->minor->dev;
struct amdgpu_device *adev = dev->dev_private;
seq_printf(m, "(%d)\n", ttm_bo_evict_mm(&adev->mman.bdev, TTM_PL_TT));
return 0;
}
static const struct drm_info_list amdgpu_debugfs_list[] = { static const struct drm_info_list amdgpu_debugfs_list[] = {
{"amdgpu_vbios", amdgpu_debugfs_get_vbios_dump}, {"amdgpu_vbios", amdgpu_debugfs_get_vbios_dump},
{"amdgpu_test_ib", &amdgpu_debugfs_test_ib}, {"amdgpu_test_ib", &amdgpu_debugfs_test_ib},
{"amdgpu_evict_vram", &amdgpu_debugfs_evict_vram} {"amdgpu_evict_vram", &amdgpu_debugfs_evict_vram},
{"amdgpu_evict_gtt", &amdgpu_debugfs_evict_gtt},
}; };
int amdgpu_debugfs_init(struct amdgpu_device *adev) int amdgpu_debugfs_init(struct amdgpu_device *adev)
......
...@@ -87,6 +87,8 @@ static const char *amdgpu_asic_name[] = { ...@@ -87,6 +87,8 @@ static const char *amdgpu_asic_name[] = {
"LAST", "LAST",
}; };
static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev);
bool amdgpu_device_is_px(struct drm_device *dev) bool amdgpu_device_is_px(struct drm_device *dev)
{ {
struct amdgpu_device *adev = dev->dev_private; struct amdgpu_device *adev = dev->dev_private;
...@@ -121,6 +123,32 @@ uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg, ...@@ -121,6 +123,32 @@ uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
return ret; return ret;
} }
/*
* MMIO register read with bytes helper functions
* @offset:bytes offset from MMIO start
*
*/
uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset) {
if (offset < adev->rmmio_size)
return (readb(adev->rmmio + offset));
BUG();
}
/*
* MMIO register write with bytes helper functions
* @offset:bytes offset from MMIO start
* @value: the value want to be written to the register
*
*/
void amdgpu_mm_wreg8(struct amdgpu_device *adev, uint32_t offset, uint8_t value) {
if (offset < adev->rmmio_size)
writeb(value, adev->rmmio + offset);
else
BUG();
}
void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v, void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
uint32_t acc_flags) uint32_t acc_flags)
{ {
...@@ -492,7 +520,7 @@ static int amdgpu_device_wb_init(struct amdgpu_device *adev) ...@@ -492,7 +520,7 @@ static int amdgpu_device_wb_init(struct amdgpu_device *adev)
memset(&adev->wb.used, 0, sizeof(adev->wb.used)); memset(&adev->wb.used, 0, sizeof(adev->wb.used));
/* clear wb memory */ /* clear wb memory */
memset((char *)adev->wb.wb, 0, AMDGPU_MAX_WB * sizeof(uint32_t)); memset((char *)adev->wb.wb, 0, AMDGPU_MAX_WB * sizeof(uint32_t) * 8);
} }
return 0; return 0;
...@@ -530,8 +558,9 @@ int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb) ...@@ -530,8 +558,9 @@ int amdgpu_device_wb_get(struct amdgpu_device *adev, u32 *wb)
*/ */
void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb) void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb)
{ {
wb >>= 3;
if (wb < adev->wb.num_wb) if (wb < adev->wb.num_wb)
__clear_bit(wb >> 3, adev->wb.used); __clear_bit(wb, adev->wb.used);
} }
/** /**
...@@ -544,7 +573,7 @@ void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb) ...@@ -544,7 +573,7 @@ void amdgpu_device_wb_free(struct amdgpu_device *adev, u32 wb)
* as parameter. * as parameter.
*/ */
void amdgpu_device_vram_location(struct amdgpu_device *adev, void amdgpu_device_vram_location(struct amdgpu_device *adev,
struct amdgpu_mc *mc, u64 base) struct amdgpu_gmc *mc, u64 base)
{ {
uint64_t limit = (uint64_t)amdgpu_vram_limit << 20; uint64_t limit = (uint64_t)amdgpu_vram_limit << 20;
...@@ -570,11 +599,11 @@ void amdgpu_device_vram_location(struct amdgpu_device *adev, ...@@ -570,11 +599,11 @@ void amdgpu_device_vram_location(struct amdgpu_device *adev,
* FIXME: when reducing GTT size align new size on power of 2. * FIXME: when reducing GTT size align new size on power of 2.
*/ */
void amdgpu_device_gart_location(struct amdgpu_device *adev, void amdgpu_device_gart_location(struct amdgpu_device *adev,
struct amdgpu_mc *mc) struct amdgpu_gmc *mc)
{ {
u64 size_af, size_bf; u64 size_af, size_bf;
size_af = adev->mc.mc_mask - mc->vram_end; size_af = adev->gmc.mc_mask - mc->vram_end;
size_bf = mc->vram_start; size_bf = mc->vram_start;
if (size_bf > size_af) { if (size_bf > size_af) {
if (mc->gart_size > size_bf) { if (mc->gart_size > size_bf) {
...@@ -608,7 +637,7 @@ void amdgpu_device_gart_location(struct amdgpu_device *adev, ...@@ -608,7 +637,7 @@ void amdgpu_device_gart_location(struct amdgpu_device *adev,
*/ */
int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev) int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev)
{ {
u64 space_needed = roundup_pow_of_two(adev->mc.real_vram_size); u64 space_needed = roundup_pow_of_two(adev->gmc.real_vram_size);
u32 rbar_size = order_base_2(((space_needed >> 20) | 1)) - 1; u32 rbar_size = order_base_2(((space_needed >> 20) | 1)) - 1;
struct pci_bus *root; struct pci_bus *root;
struct resource *res; struct resource *res;
...@@ -829,6 +858,8 @@ static void amdgpu_device_check_arguments(struct amdgpu_device *adev) ...@@ -829,6 +858,8 @@ static void amdgpu_device_check_arguments(struct amdgpu_device *adev)
dev_warn(adev->dev, "lockup_timeout msut be > 0, adjusting to 10000\n"); dev_warn(adev->dev, "lockup_timeout msut be > 0, adjusting to 10000\n");
amdgpu_lockup_timeout = 10000; amdgpu_lockup_timeout = 10000;
} }
adev->firmware.load_type = amdgpu_ucode_get_load_type(adev, amdgpu_fw_load_type);
} }
/** /**
...@@ -1036,7 +1067,7 @@ int amdgpu_device_ip_block_add(struct amdgpu_device *adev, ...@@ -1036,7 +1067,7 @@ int amdgpu_device_ip_block_add(struct amdgpu_device *adev,
if (!ip_block_version) if (!ip_block_version)
return -EINVAL; return -EINVAL;
DRM_DEBUG("add ip block number %d <%s>\n", adev->num_ip_blocks, DRM_INFO("add ip block number %d <%s>\n", adev->num_ip_blocks,
ip_block_version->funcs->name); ip_block_version->funcs->name);
adev->ip_blocks[adev->num_ip_blocks++].version = ip_block_version; adev->ip_blocks[adev->num_ip_blocks++].version = ip_block_version;
...@@ -1310,6 +1341,7 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) ...@@ -1310,6 +1341,7 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
return r; return r;
} }
adev->ip_blocks[i].status.sw = true; adev->ip_blocks[i].status.sw = true;
/* need to do gmc hw init early so we can allocate gpu mem */ /* need to do gmc hw init early so we can allocate gpu mem */
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) { if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) {
r = amdgpu_device_vram_scratch_init(adev); r = amdgpu_device_vram_scratch_init(adev);
...@@ -1343,8 +1375,7 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) ...@@ -1343,8 +1375,7 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
for (i = 0; i < adev->num_ip_blocks; i++) { for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_blocks[i].status.sw) if (!adev->ip_blocks[i].status.sw)
continue; continue;
/* gmc hw init is done early */ if (adev->ip_blocks[i].status.hw)
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC)
continue; continue;
r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev); r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev);
if (r) { if (r) {
...@@ -1378,12 +1409,16 @@ static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev) ...@@ -1378,12 +1409,16 @@ static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev)
{ {
int i = 0, r; int i = 0, r;
if (amdgpu_emu_mode == 1)
return 0;
for (i = 0; i < adev->num_ip_blocks; i++) { for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_blocks[i].status.valid) if (!adev->ip_blocks[i].status.valid)
continue; continue;
/* skip CG for VCE/UVD, it's handled specially */ /* skip CG for VCE/UVD, it's handled specially */
if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD && if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE) { adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE &&
adev->ip_blocks[i].version->funcs->set_clockgating_state) {
/* enable clockgating to save power */ /* enable clockgating to save power */
r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev, r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev,
AMD_CG_STATE_GATE); AMD_CG_STATE_GATE);
...@@ -1432,7 +1467,8 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) ...@@ -1432,7 +1467,8 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
for (i = 0; i < adev->num_ip_blocks; i++) { for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_blocks[i].status.hw) if (!adev->ip_blocks[i].status.hw)
continue; continue;
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) { if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC &&
adev->ip_blocks[i].version->funcs->set_clockgating_state) {
/* ungate blocks before hw fini so that we can shutdown the blocks safely */ /* ungate blocks before hw fini so that we can shutdown the blocks safely */
r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev, r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev,
AMD_CG_STATE_UNGATE); AMD_CG_STATE_UNGATE);
...@@ -1455,11 +1491,6 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) ...@@ -1455,11 +1491,6 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
for (i = adev->num_ip_blocks - 1; i >= 0; i--) { for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
if (!adev->ip_blocks[i].status.hw) if (!adev->ip_blocks[i].status.hw)
continue; continue;
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) {
amdgpu_free_static_csa(adev);
amdgpu_device_wb_fini(adev);
amdgpu_device_vram_scratch_fini(adev);
}
if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD && if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD &&
adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE) { adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE) {
...@@ -1483,9 +1514,19 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) ...@@ -1483,9 +1514,19 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
adev->ip_blocks[i].status.hw = false; adev->ip_blocks[i].status.hw = false;
} }
/* disable all interrupts */
amdgpu_irq_disable_all(adev);
for (i = adev->num_ip_blocks - 1; i >= 0; i--) { for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
if (!adev->ip_blocks[i].status.sw) if (!adev->ip_blocks[i].status.sw)
continue; continue;
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) {
amdgpu_free_static_csa(adev);
amdgpu_device_wb_fini(adev);
amdgpu_device_vram_scratch_fini(adev);
}
r = adev->ip_blocks[i].version->funcs->sw_fini((void *)adev); r = adev->ip_blocks[i].version->funcs->sw_fini((void *)adev);
/* XXX handle errors */ /* XXX handle errors */
if (r) { if (r) {
...@@ -1536,7 +1577,8 @@ int amdgpu_device_ip_suspend(struct amdgpu_device *adev) ...@@ -1536,7 +1577,8 @@ int amdgpu_device_ip_suspend(struct amdgpu_device *adev)
if (!adev->ip_blocks[i].status.valid) if (!adev->ip_blocks[i].status.valid)
continue; continue;
/* ungate blocks so that suspend can properly shut them down */ /* ungate blocks so that suspend can properly shut them down */
if (i != AMD_IP_BLOCK_TYPE_SMC) { if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_SMC &&
adev->ip_blocks[i].version->funcs->set_clockgating_state) {
r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev, r = adev->ip_blocks[i].version->funcs->set_clockgating_state((void *)adev,
AMD_CG_STATE_UNGATE); AMD_CG_STATE_UNGATE);
if (r) { if (r) {
...@@ -1582,6 +1624,8 @@ static int amdgpu_device_ip_reinit_early_sriov(struct amdgpu_device *adev) ...@@ -1582,6 +1624,8 @@ static int amdgpu_device_ip_reinit_early_sriov(struct amdgpu_device *adev)
r = block->version->funcs->hw_init(adev); r = block->version->funcs->hw_init(adev);
DRM_INFO("RE-INIT: %s %s\n", block->version->funcs->name, r?"failed":"successed"); DRM_INFO("RE-INIT: %s %s\n", block->version->funcs->name, r?"failed":"successed");
if (r)
return r;
} }
} }
...@@ -1615,6 +1659,8 @@ static int amdgpu_device_ip_reinit_late_sriov(struct amdgpu_device *adev) ...@@ -1615,6 +1659,8 @@ static int amdgpu_device_ip_reinit_late_sriov(struct amdgpu_device *adev)
r = block->version->funcs->hw_init(adev); r = block->version->funcs->hw_init(adev);
DRM_INFO("RE-INIT: %s %s\n", block->version->funcs->name, r?"failed":"successed"); DRM_INFO("RE-INIT: %s %s\n", block->version->funcs->name, r?"failed":"successed");
if (r)
return r;
} }
} }
...@@ -1701,6 +1747,8 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) ...@@ -1701,6 +1747,8 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
case CHIP_BONAIRE: case CHIP_BONAIRE:
case CHIP_HAWAII: case CHIP_HAWAII:
case CHIP_KAVERI: case CHIP_KAVERI:
case CHIP_KABINI:
case CHIP_MULLINS:
case CHIP_CARRIZO: case CHIP_CARRIZO:
case CHIP_STONEY: case CHIP_STONEY:
case CHIP_POLARIS11: case CHIP_POLARIS11:
...@@ -1711,9 +1759,6 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) ...@@ -1711,9 +1759,6 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type)
#if defined(CONFIG_DRM_AMD_DC_PRE_VEGA) #if defined(CONFIG_DRM_AMD_DC_PRE_VEGA)
return amdgpu_dc != 0; return amdgpu_dc != 0;
#endif #endif
case CHIP_KABINI:
case CHIP_MULLINS:
return amdgpu_dc > 0;
case CHIP_VEGA10: case CHIP_VEGA10:
#if defined(CONFIG_DRM_AMD_DC_DCN1_0) #if defined(CONFIG_DRM_AMD_DC_DCN1_0)
case CHIP_RAVEN: case CHIP_RAVEN:
...@@ -1768,14 +1813,16 @@ int amdgpu_device_init(struct amdgpu_device *adev, ...@@ -1768,14 +1813,16 @@ int amdgpu_device_init(struct amdgpu_device *adev,
adev->flags = flags; adev->flags = flags;
adev->asic_type = flags & AMD_ASIC_MASK; adev->asic_type = flags & AMD_ASIC_MASK;
adev->usec_timeout = AMDGPU_MAX_USEC_TIMEOUT; adev->usec_timeout = AMDGPU_MAX_USEC_TIMEOUT;
adev->mc.gart_size = 512 * 1024 * 1024; if (amdgpu_emu_mode == 1)
adev->usec_timeout *= 2;
adev->gmc.gart_size = 512 * 1024 * 1024;
adev->accel_working = false; adev->accel_working = false;
adev->num_rings = 0; adev->num_rings = 0;
adev->mman.buffer_funcs = NULL; adev->mman.buffer_funcs = NULL;
adev->mman.buffer_funcs_ring = NULL; adev->mman.buffer_funcs_ring = NULL;
adev->vm_manager.vm_pte_funcs = NULL; adev->vm_manager.vm_pte_funcs = NULL;
adev->vm_manager.vm_pte_num_rings = 0; adev->vm_manager.vm_pte_num_rings = 0;
adev->gart.gart_funcs = NULL; adev->gmc.gmc_funcs = NULL;
adev->fence_context = dma_fence_context_alloc(AMDGPU_MAX_RINGS); adev->fence_context = dma_fence_context_alloc(AMDGPU_MAX_RINGS);
bitmap_zero(adev->gfx.pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES); bitmap_zero(adev->gfx.pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES);
...@@ -1864,6 +1911,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, ...@@ -1864,6 +1911,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
if (adev->rio_mem == NULL) if (adev->rio_mem == NULL)
DRM_INFO("PCI I/O BAR is not found.\n"); DRM_INFO("PCI I/O BAR is not found.\n");
amdgpu_device_get_pcie_info(adev);
/* early init functions */ /* early init functions */
r = amdgpu_device_ip_early_init(adev); r = amdgpu_device_ip_early_init(adev);
if (r) if (r)
...@@ -1882,6 +1931,12 @@ int amdgpu_device_init(struct amdgpu_device *adev, ...@@ -1882,6 +1931,12 @@ int amdgpu_device_init(struct amdgpu_device *adev,
if (runtime) if (runtime)
vga_switcheroo_init_domain_pm_ops(adev->dev, &adev->vga_pm_domain); vga_switcheroo_init_domain_pm_ops(adev->dev, &adev->vga_pm_domain);
if (amdgpu_emu_mode == 1) {
/* post the asic on emulation mode */
emu_soc_asic_init(adev);
goto fence_driver_init;
}
/* Read BIOS */ /* Read BIOS */
if (!amdgpu_get_bios(adev)) { if (!amdgpu_get_bios(adev)) {
r = -EINVAL; r = -EINVAL;
...@@ -1934,6 +1989,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, ...@@ -1934,6 +1989,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
amdgpu_atombios_i2c_init(adev); amdgpu_atombios_i2c_init(adev);
} }
fence_driver_init:
/* Fence driver */ /* Fence driver */
r = amdgpu_fence_driver_init(adev); r = amdgpu_fence_driver_init(adev);
if (r) { if (r) {
...@@ -2065,6 +2121,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev) ...@@ -2065,6 +2121,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
amdgpu_ib_pool_fini(adev); amdgpu_ib_pool_fini(adev);
amdgpu_fence_driver_fini(adev); amdgpu_fence_driver_fini(adev);
amdgpu_pm_sysfs_fini(adev);
amdgpu_fbdev_fini(adev); amdgpu_fbdev_fini(adev);
r = amdgpu_device_ip_fini(adev); r = amdgpu_device_ip_fini(adev);
if (adev->firmware.gpu_info_fw) { if (adev->firmware.gpu_info_fw) {
...@@ -2076,7 +2133,10 @@ void amdgpu_device_fini(struct amdgpu_device *adev) ...@@ -2076,7 +2133,10 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
/* free i2c buses */ /* free i2c buses */
if (!amdgpu_device_has_dc_support(adev)) if (!amdgpu_device_has_dc_support(adev))
amdgpu_i2c_fini(adev); amdgpu_i2c_fini(adev);
amdgpu_atombios_fini(adev);
if (amdgpu_emu_mode != 1)
amdgpu_atombios_fini(adev);
kfree(adev->bios); kfree(adev->bios);
adev->bios = NULL; adev->bios = NULL;
if (!pci_is_thunderbolt_attached(adev->pdev)) if (!pci_is_thunderbolt_attached(adev->pdev))
...@@ -2090,7 +2150,6 @@ void amdgpu_device_fini(struct amdgpu_device *adev) ...@@ -2090,7 +2150,6 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
iounmap(adev->rmmio); iounmap(adev->rmmio);
adev->rmmio = NULL; adev->rmmio = NULL;
amdgpu_device_doorbell_fini(adev); amdgpu_device_doorbell_fini(adev);
amdgpu_pm_sysfs_fini(adev);
amdgpu_debugfs_regs_cleanup(adev); amdgpu_debugfs_regs_cleanup(adev);
} }
...@@ -2284,14 +2343,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) ...@@ -2284,14 +2343,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
} }
drm_modeset_unlock_all(dev); drm_modeset_unlock_all(dev);
} else {
/*
* There is no equivalent atomic helper to turn on
* display, so we defined our own function for this,
* once suspend resume is supported by the atomic
* framework this will be reworked
*/
amdgpu_dm_display_resume(adev);
} }
} }
...@@ -2458,17 +2509,71 @@ static int amdgpu_device_recover_vram_from_shadow(struct amdgpu_device *adev, ...@@ -2458,17 +2509,71 @@ static int amdgpu_device_recover_vram_from_shadow(struct amdgpu_device *adev,
return r; return r;
} }
static int amdgpu_device_handle_vram_lost(struct amdgpu_device *adev)
{
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
struct amdgpu_bo *bo, *tmp;
struct dma_fence *fence = NULL, *next = NULL;
long r = 1;
int i = 0;
long tmo;
if (amdgpu_sriov_runtime(adev))
tmo = msecs_to_jiffies(amdgpu_lockup_timeout);
else
tmo = msecs_to_jiffies(100);
DRM_INFO("recover vram bo from shadow start\n");
mutex_lock(&adev->shadow_list_lock);
list_for_each_entry_safe(bo, tmp, &adev->shadow_list, shadow_list) {
next = NULL;
amdgpu_device_recover_vram_from_shadow(adev, ring, bo, &next);
if (fence) {
r = dma_fence_wait_timeout(fence, false, tmo);
if (r == 0)
pr_err("wait fence %p[%d] timeout\n", fence, i);
else if (r < 0)
pr_err("wait fence %p[%d] interrupted\n", fence, i);
if (r < 1) {
dma_fence_put(fence);
fence = next;
break;
}
i++;
}
dma_fence_put(fence);
fence = next;
}
mutex_unlock(&adev->shadow_list_lock);
if (fence) {
r = dma_fence_wait_timeout(fence, false, tmo);
if (r == 0)
pr_err("wait fence %p[%d] timeout\n", fence, i);
else if (r < 0)
pr_err("wait fence %p[%d] interrupted\n", fence, i);
}
dma_fence_put(fence);
if (r > 0)
DRM_INFO("recover vram bo from shadow done\n");
else
DRM_ERROR("recover vram bo from shadow failed\n");
return (r > 0?0:1);
}
/* /*
* amdgpu_device_reset - reset ASIC/GPU for bare-metal or passthrough * amdgpu_device_reset - reset ASIC/GPU for bare-metal or passthrough
* *
* @adev: amdgpu device pointer * @adev: amdgpu device pointer
* @reset_flags: output param tells caller the reset result
* *
* attempt to do soft-reset or full-reset and reinitialize Asic * attempt to do soft-reset or full-reset and reinitialize Asic
* return 0 means successed otherwise failed * return 0 means successed otherwise failed
*/ */
static int amdgpu_device_reset(struct amdgpu_device *adev, static int amdgpu_device_reset(struct amdgpu_device *adev)
uint64_t* reset_flags)
{ {
bool need_full_reset, vram_lost = 0; bool need_full_reset, vram_lost = 0;
int r; int r;
...@@ -2483,7 +2588,6 @@ static int amdgpu_device_reset(struct amdgpu_device *adev, ...@@ -2483,7 +2588,6 @@ static int amdgpu_device_reset(struct amdgpu_device *adev,
DRM_INFO("soft reset failed, will fallback to full reset!\n"); DRM_INFO("soft reset failed, will fallback to full reset!\n");
need_full_reset = true; need_full_reset = true;
} }
} }
if (need_full_reset) { if (need_full_reset) {
...@@ -2532,13 +2636,8 @@ static int amdgpu_device_reset(struct amdgpu_device *adev, ...@@ -2532,13 +2636,8 @@ static int amdgpu_device_reset(struct amdgpu_device *adev,
} }
} }
if (reset_flags) { if (!r && ((need_full_reset && !(adev->flags & AMD_IS_APU)) || vram_lost))
if (vram_lost) r = amdgpu_device_handle_vram_lost(adev);
(*reset_flags) |= AMDGPU_RESET_INFO_VRAM_LOST;
if (need_full_reset)
(*reset_flags) |= AMDGPU_RESET_INFO_FULLRESET;
}
return r; return r;
} }
...@@ -2547,14 +2646,11 @@ static int amdgpu_device_reset(struct amdgpu_device *adev, ...@@ -2547,14 +2646,11 @@ static int amdgpu_device_reset(struct amdgpu_device *adev,
* amdgpu_device_reset_sriov - reset ASIC for SR-IOV vf * amdgpu_device_reset_sriov - reset ASIC for SR-IOV vf
* *
* @adev: amdgpu device pointer * @adev: amdgpu device pointer
* @reset_flags: output param tells caller the reset result
* *
* do VF FLR and reinitialize Asic * do VF FLR and reinitialize Asic
* return 0 means successed otherwise failed * return 0 means successed otherwise failed
*/ */
static int amdgpu_device_reset_sriov(struct amdgpu_device *adev, static int amdgpu_device_reset_sriov(struct amdgpu_device *adev, bool from_hypervisor)
uint64_t *reset_flags,
bool from_hypervisor)
{ {
int r; int r;
...@@ -2575,28 +2671,20 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev, ...@@ -2575,28 +2671,20 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev,
/* now we are okay to resume SMC/CP/SDMA */ /* now we are okay to resume SMC/CP/SDMA */
r = amdgpu_device_ip_reinit_late_sriov(adev); r = amdgpu_device_ip_reinit_late_sriov(adev);
amdgpu_virt_release_full_gpu(adev, true);
if (r) if (r)
goto error; goto error;
amdgpu_irq_gpu_reset_resume_helper(adev); amdgpu_irq_gpu_reset_resume_helper(adev);
r = amdgpu_ib_ring_tests(adev); r = amdgpu_ib_ring_tests(adev);
if (r)
dev_err(adev->dev, "[GPU_RESET] ib ring test failed (%d).\n", r);
error:
/* release full control of GPU after ib test */
amdgpu_virt_release_full_gpu(adev, true);
if (reset_flags) { if (!r && adev->virt.gim_feature & AMDGIM_FEATURE_GIM_FLR_VRAMLOST) {
if (adev->virt.gim_feature & AMDGIM_FEATURE_GIM_FLR_VRAMLOST) { atomic_inc(&adev->vram_lost_counter);
(*reset_flags) |= AMDGPU_RESET_INFO_VRAM_LOST; r = amdgpu_device_handle_vram_lost(adev);
atomic_inc(&adev->vram_lost_counter);
}
/* VF FLR or hotlink reset is always full-reset */
(*reset_flags) |= AMDGPU_RESET_INFO_FULLRESET;
} }
error:
return r; return r;
} }
...@@ -2614,7 +2702,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, ...@@ -2614,7 +2702,6 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
struct amdgpu_job *job, bool force) struct amdgpu_job *job, bool force)
{ {
struct drm_atomic_state *state = NULL; struct drm_atomic_state *state = NULL;
uint64_t reset_flags = 0;
int i, r, resched; int i, r, resched;
if (!force && !amdgpu_device_ip_check_soft_reset(adev)) { if (!force && !amdgpu_device_ip_check_soft_reset(adev)) {
...@@ -2636,22 +2723,23 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, ...@@ -2636,22 +2723,23 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
/* block TTM */ /* block TTM */
resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev); resched = ttm_bo_lock_delayed_workqueue(&adev->mman.bdev);
/* store modesetting */ /* store modesetting */
if (amdgpu_device_has_dc_support(adev)) if (amdgpu_device_has_dc_support(adev))
state = drm_atomic_helper_suspend(adev->ddev); state = drm_atomic_helper_suspend(adev->ddev);
/* block scheduler */ /* block all schedulers and reset given job's ring */
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
struct amdgpu_ring *ring = adev->rings[i]; struct amdgpu_ring *ring = adev->rings[i];
if (!ring || !ring->sched.thread) if (!ring || !ring->sched.thread)
continue; continue;
/* only focus on the ring hit timeout if &job not NULL */ kthread_park(ring->sched.thread);
if (job && job->ring->idx != i) if (job && job->ring->idx != i)
continue; continue;
kthread_park(ring->sched.thread);
drm_sched_hw_job_reset(&ring->sched, &job->base); drm_sched_hw_job_reset(&ring->sched, &job->base);
/* after all hw jobs are reset, hw fence is meaningless, so force_completion */ /* after all hw jobs are reset, hw fence is meaningless, so force_completion */
...@@ -2659,74 +2747,29 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, ...@@ -2659,74 +2747,29 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
} }
if (amdgpu_sriov_vf(adev)) if (amdgpu_sriov_vf(adev))
r = amdgpu_device_reset_sriov(adev, &reset_flags, job ? false : true); r = amdgpu_device_reset_sriov(adev, job ? false : true);
else else
r = amdgpu_device_reset(adev, &reset_flags); r = amdgpu_device_reset(adev);
if (!r) { for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
if (((reset_flags & AMDGPU_RESET_INFO_FULLRESET) && !(adev->flags & AMD_IS_APU)) || struct amdgpu_ring *ring = adev->rings[i];
(reset_flags & AMDGPU_RESET_INFO_VRAM_LOST)) {
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
struct amdgpu_bo *bo, *tmp;
struct dma_fence *fence = NULL, *next = NULL;
DRM_INFO("recover vram bo from shadow\n");
mutex_lock(&adev->shadow_list_lock);
list_for_each_entry_safe(bo, tmp, &adev->shadow_list, shadow_list) {
next = NULL;
amdgpu_device_recover_vram_from_shadow(adev, ring, bo, &next);
if (fence) {
r = dma_fence_wait(fence, false);
if (r) {
WARN(r, "recovery from shadow isn't completed\n");
break;
}
}
dma_fence_put(fence);
fence = next;
}
mutex_unlock(&adev->shadow_list_lock);
if (fence) {
r = dma_fence_wait(fence, false);
if (r)
WARN(r, "recovery from shadow isn't completed\n");
}
dma_fence_put(fence);
}
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
struct amdgpu_ring *ring = adev->rings[i];
if (!ring || !ring->sched.thread)
continue;
/* only focus on the ring hit timeout if &job not NULL */ if (!ring || !ring->sched.thread)
if (job && job->ring->idx != i) continue;
continue;
/* only need recovery sched of the given job's ring
* or all rings (in the case @job is NULL)
* after above amdgpu_reset accomplished
*/
if ((!job || job->ring->idx == i) && !r)
drm_sched_job_recovery(&ring->sched); drm_sched_job_recovery(&ring->sched);
kthread_unpark(ring->sched.thread);
}
} else {
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
struct amdgpu_ring *ring = adev->rings[i];
if (!ring || !ring->sched.thread)
continue;
/* only focus on the ring hit timeout if &job not NULL */ kthread_unpark(ring->sched.thread);
if (job && job->ring->idx != i)
continue;
kthread_unpark(adev->rings[i]->sched.thread);
}
} }
if (amdgpu_device_has_dc_support(adev)) { if (amdgpu_device_has_dc_support(adev)) {
if (drm_atomic_helper_resume(adev->ddev, state)) if (drm_atomic_helper_resume(adev->ddev, state))
dev_info(adev->dev, "drm resume failed:%d\n", r); dev_info(adev->dev, "drm resume failed:%d\n", r);
amdgpu_dm_display_resume(adev);
} else { } else {
drm_helper_resume_force_mode(adev->ddev); drm_helper_resume_force_mode(adev->ddev);
} }
...@@ -2747,7 +2790,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, ...@@ -2747,7 +2790,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
return r; return r;
} }
void amdgpu_device_get_pcie_info(struct amdgpu_device *adev) static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
{ {
u32 mask; u32 mask;
int ret; int ret;
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "amdgpu_i2c.h" #include "amdgpu_i2c.h"
#include "atom.h" #include "atom.h"
#include "amdgpu_connectors.h" #include "amdgpu_connectors.h"
#include "amdgpu_display.h"
#include <asm/div64.h> #include <asm/div64.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
...@@ -36,7 +37,8 @@ ...@@ -36,7 +37,8 @@
#include <drm/drm_edid.h> #include <drm/drm_edid.h>
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
static void amdgpu_flip_callback(struct dma_fence *f, struct dma_fence_cb *cb) static void amdgpu_display_flip_callback(struct dma_fence *f,
struct dma_fence_cb *cb)
{ {
struct amdgpu_flip_work *work = struct amdgpu_flip_work *work =
container_of(cb, struct amdgpu_flip_work, cb); container_of(cb, struct amdgpu_flip_work, cb);
...@@ -45,8 +47,8 @@ static void amdgpu_flip_callback(struct dma_fence *f, struct dma_fence_cb *cb) ...@@ -45,8 +47,8 @@ static void amdgpu_flip_callback(struct dma_fence *f, struct dma_fence_cb *cb)
schedule_work(&work->flip_work.work); schedule_work(&work->flip_work.work);
} }
static bool amdgpu_flip_handle_fence(struct amdgpu_flip_work *work, static bool amdgpu_display_flip_handle_fence(struct amdgpu_flip_work *work,
struct dma_fence **f) struct dma_fence **f)
{ {
struct dma_fence *fence= *f; struct dma_fence *fence= *f;
...@@ -55,14 +57,15 @@ static bool amdgpu_flip_handle_fence(struct amdgpu_flip_work *work, ...@@ -55,14 +57,15 @@ static bool amdgpu_flip_handle_fence(struct amdgpu_flip_work *work,
*f = NULL; *f = NULL;
if (!dma_fence_add_callback(fence, &work->cb, amdgpu_flip_callback)) if (!dma_fence_add_callback(fence, &work->cb,
amdgpu_display_flip_callback))
return true; return true;
dma_fence_put(fence); dma_fence_put(fence);
return false; return false;
} }
static void amdgpu_flip_work_func(struct work_struct *__work) static void amdgpu_display_flip_work_func(struct work_struct *__work)
{ {
struct delayed_work *delayed_work = struct delayed_work *delayed_work =
container_of(__work, struct delayed_work, work); container_of(__work, struct delayed_work, work);
...@@ -76,20 +79,20 @@ static void amdgpu_flip_work_func(struct work_struct *__work) ...@@ -76,20 +79,20 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
unsigned i; unsigned i;
int vpos, hpos; int vpos, hpos;
if (amdgpu_flip_handle_fence(work, &work->excl)) if (amdgpu_display_flip_handle_fence(work, &work->excl))
return; return;
for (i = 0; i < work->shared_count; ++i) for (i = 0; i < work->shared_count; ++i)
if (amdgpu_flip_handle_fence(work, &work->shared[i])) if (amdgpu_display_flip_handle_fence(work, &work->shared[i]))
return; return;
/* Wait until we're out of the vertical blank period before the one /* Wait until we're out of the vertical blank period before the one
* targeted by the flip * targeted by the flip
*/ */
if (amdgpu_crtc->enabled && if (amdgpu_crtc->enabled &&
(amdgpu_get_crtc_scanoutpos(adev->ddev, work->crtc_id, 0, (amdgpu_display_get_crtc_scanoutpos(adev->ddev, work->crtc_id, 0,
&vpos, &hpos, NULL, NULL, &vpos, &hpos, NULL, NULL,
&crtc->hwmode) &crtc->hwmode)
& (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK)) == & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK)) ==
(DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK) && (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_IN_VBLANK) &&
(int)(work->target_vblank - (int)(work->target_vblank -
...@@ -117,7 +120,7 @@ static void amdgpu_flip_work_func(struct work_struct *__work) ...@@ -117,7 +120,7 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
/* /*
* Handle unpin events outside the interrupt handler proper. * Handle unpin events outside the interrupt handler proper.
*/ */
static void amdgpu_unpin_work_func(struct work_struct *__work) static void amdgpu_display_unpin_work_func(struct work_struct *__work)
{ {
struct amdgpu_flip_work *work = struct amdgpu_flip_work *work =
container_of(__work, struct amdgpu_flip_work, unpin_work); container_of(__work, struct amdgpu_flip_work, unpin_work);
...@@ -139,11 +142,11 @@ static void amdgpu_unpin_work_func(struct work_struct *__work) ...@@ -139,11 +142,11 @@ static void amdgpu_unpin_work_func(struct work_struct *__work)
kfree(work); kfree(work);
} }
int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc, int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc,
struct drm_framebuffer *fb, struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event, struct drm_pending_vblank_event *event,
uint32_t page_flip_flags, uint32_t target, uint32_t page_flip_flags, uint32_t target,
struct drm_modeset_acquire_ctx *ctx) struct drm_modeset_acquire_ctx *ctx)
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct amdgpu_device *adev = dev->dev_private; struct amdgpu_device *adev = dev->dev_private;
...@@ -162,8 +165,8 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc, ...@@ -162,8 +165,8 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
if (work == NULL) if (work == NULL)
return -ENOMEM; return -ENOMEM;
INIT_DELAYED_WORK(&work->flip_work, amdgpu_flip_work_func); INIT_DELAYED_WORK(&work->flip_work, amdgpu_display_flip_work_func);
INIT_WORK(&work->unpin_work, amdgpu_unpin_work_func); INIT_WORK(&work->unpin_work, amdgpu_display_unpin_work_func);
work->event = event; work->event = event;
work->adev = adev; work->adev = adev;
...@@ -189,7 +192,7 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc, ...@@ -189,7 +192,7 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
goto cleanup; goto cleanup;
} }
r = amdgpu_bo_pin(new_abo, AMDGPU_GEM_DOMAIN_VRAM, &base); r = amdgpu_bo_pin(new_abo, amdgpu_display_framebuffer_domains(adev), &base);
if (unlikely(r != 0)) { if (unlikely(r != 0)) {
DRM_ERROR("failed to pin new abo buffer before flip\n"); DRM_ERROR("failed to pin new abo buffer before flip\n");
goto unreserve; goto unreserve;
...@@ -207,7 +210,7 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc, ...@@ -207,7 +210,7 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
amdgpu_bo_unreserve(new_abo); amdgpu_bo_unreserve(new_abo);
work->base = base; work->base = base;
work->target_vblank = target - drm_crtc_vblank_count(crtc) + work->target_vblank = target - (uint32_t)drm_crtc_vblank_count(crtc) +
amdgpu_get_vblank_counter_kms(dev, work->crtc_id); amdgpu_get_vblank_counter_kms(dev, work->crtc_id);
/* we borrow the event spin lock for protecting flip_wrok */ /* we borrow the event spin lock for protecting flip_wrok */
...@@ -228,7 +231,7 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc, ...@@ -228,7 +231,7 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
/* update crtc fb */ /* update crtc fb */
crtc->primary->fb = fb; crtc->primary->fb = fb;
spin_unlock_irqrestore(&crtc->dev->event_lock, flags); spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
amdgpu_flip_work_func(&work->flip_work.work); amdgpu_display_flip_work_func(&work->flip_work.work);
return 0; return 0;
pflip_cleanup: pflip_cleanup:
...@@ -254,8 +257,8 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc, ...@@ -254,8 +257,8 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
return r; return r;
} }
int amdgpu_crtc_set_config(struct drm_mode_set *set, int amdgpu_display_crtc_set_config(struct drm_mode_set *set,
struct drm_modeset_acquire_ctx *ctx) struct drm_modeset_acquire_ctx *ctx)
{ {
struct drm_device *dev; struct drm_device *dev;
struct amdgpu_device *adev; struct amdgpu_device *adev;
...@@ -352,7 +355,7 @@ static const char *hpd_names[6] = { ...@@ -352,7 +355,7 @@ static const char *hpd_names[6] = {
"HPD6", "HPD6",
}; };
void amdgpu_print_display_setup(struct drm_device *dev) void amdgpu_display_print_display_setup(struct drm_device *dev)
{ {
struct drm_connector *connector; struct drm_connector *connector;
struct amdgpu_connector *amdgpu_connector; struct amdgpu_connector *amdgpu_connector;
...@@ -429,11 +432,11 @@ void amdgpu_print_display_setup(struct drm_device *dev) ...@@ -429,11 +432,11 @@ void amdgpu_print_display_setup(struct drm_device *dev)
} }
/** /**
* amdgpu_ddc_probe * amdgpu_display_ddc_probe
* *
*/ */
bool amdgpu_ddc_probe(struct amdgpu_connector *amdgpu_connector, bool amdgpu_display_ddc_probe(struct amdgpu_connector *amdgpu_connector,
bool use_aux) bool use_aux)
{ {
u8 out = 0x0; u8 out = 0x0;
u8 buf[8]; u8 buf[8];
...@@ -479,7 +482,7 @@ bool amdgpu_ddc_probe(struct amdgpu_connector *amdgpu_connector, ...@@ -479,7 +482,7 @@ bool amdgpu_ddc_probe(struct amdgpu_connector *amdgpu_connector,
return true; return true;
} }
static void amdgpu_user_framebuffer_destroy(struct drm_framebuffer *fb) static void amdgpu_display_user_framebuffer_destroy(struct drm_framebuffer *fb)
{ {
struct amdgpu_framebuffer *amdgpu_fb = to_amdgpu_framebuffer(fb); struct amdgpu_framebuffer *amdgpu_fb = to_amdgpu_framebuffer(fb);
...@@ -488,9 +491,10 @@ static void amdgpu_user_framebuffer_destroy(struct drm_framebuffer *fb) ...@@ -488,9 +491,10 @@ static void amdgpu_user_framebuffer_destroy(struct drm_framebuffer *fb)
kfree(amdgpu_fb); kfree(amdgpu_fb);
} }
static int amdgpu_user_framebuffer_create_handle(struct drm_framebuffer *fb, static int amdgpu_display_user_framebuffer_create_handle(
struct drm_file *file_priv, struct drm_framebuffer *fb,
unsigned int *handle) struct drm_file *file_priv,
unsigned int *handle)
{ {
struct amdgpu_framebuffer *amdgpu_fb = to_amdgpu_framebuffer(fb); struct amdgpu_framebuffer *amdgpu_fb = to_amdgpu_framebuffer(fb);
...@@ -498,15 +502,28 @@ static int amdgpu_user_framebuffer_create_handle(struct drm_framebuffer *fb, ...@@ -498,15 +502,28 @@ static int amdgpu_user_framebuffer_create_handle(struct drm_framebuffer *fb,
} }
static const struct drm_framebuffer_funcs amdgpu_fb_funcs = { static const struct drm_framebuffer_funcs amdgpu_fb_funcs = {
.destroy = amdgpu_user_framebuffer_destroy, .destroy = amdgpu_display_user_framebuffer_destroy,
.create_handle = amdgpu_user_framebuffer_create_handle, .create_handle = amdgpu_display_user_framebuffer_create_handle,
}; };
int uint32_t amdgpu_display_framebuffer_domains(struct amdgpu_device *adev)
amdgpu_framebuffer_init(struct drm_device *dev, {
struct amdgpu_framebuffer *rfb, uint32_t domain = AMDGPU_GEM_DOMAIN_VRAM;
const struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_gem_object *obj) #if defined(CONFIG_DRM_AMD_DC)
if (adev->asic_type >= CHIP_CARRIZO && adev->asic_type < CHIP_RAVEN &&
adev->flags & AMD_IS_APU &&
amdgpu_device_asic_has_dc_support(adev->asic_type))
domain |= AMDGPU_GEM_DOMAIN_GTT;
#endif
return domain;
}
int amdgpu_display_framebuffer_init(struct drm_device *dev,
struct amdgpu_framebuffer *rfb,
const struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_gem_object *obj)
{ {
int ret; int ret;
rfb->obj = obj; rfb->obj = obj;
...@@ -520,9 +537,9 @@ amdgpu_framebuffer_init(struct drm_device *dev, ...@@ -520,9 +537,9 @@ amdgpu_framebuffer_init(struct drm_device *dev,
} }
struct drm_framebuffer * struct drm_framebuffer *
amdgpu_user_framebuffer_create(struct drm_device *dev, amdgpu_display_user_framebuffer_create(struct drm_device *dev,
struct drm_file *file_priv, struct drm_file *file_priv,
const struct drm_mode_fb_cmd2 *mode_cmd) const struct drm_mode_fb_cmd2 *mode_cmd)
{ {
struct drm_gem_object *obj; struct drm_gem_object *obj;
struct amdgpu_framebuffer *amdgpu_fb; struct amdgpu_framebuffer *amdgpu_fb;
...@@ -547,7 +564,7 @@ amdgpu_user_framebuffer_create(struct drm_device *dev, ...@@ -547,7 +564,7 @@ amdgpu_user_framebuffer_create(struct drm_device *dev,
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
ret = amdgpu_framebuffer_init(dev, amdgpu_fb, mode_cmd, obj); ret = amdgpu_display_framebuffer_init(dev, amdgpu_fb, mode_cmd, obj);
if (ret) { if (ret) {
kfree(amdgpu_fb); kfree(amdgpu_fb);
drm_gem_object_put_unlocked(obj); drm_gem_object_put_unlocked(obj);
...@@ -558,7 +575,7 @@ amdgpu_user_framebuffer_create(struct drm_device *dev, ...@@ -558,7 +575,7 @@ amdgpu_user_framebuffer_create(struct drm_device *dev,
} }
const struct drm_mode_config_funcs amdgpu_mode_funcs = { const struct drm_mode_config_funcs amdgpu_mode_funcs = {
.fb_create = amdgpu_user_framebuffer_create, .fb_create = amdgpu_display_user_framebuffer_create,
.output_poll_changed = drm_fb_helper_output_poll_changed, .output_poll_changed = drm_fb_helper_output_poll_changed,
}; };
...@@ -580,7 +597,7 @@ static const struct drm_prop_enum_list amdgpu_dither_enum_list[] = ...@@ -580,7 +597,7 @@ static const struct drm_prop_enum_list amdgpu_dither_enum_list[] =
{ AMDGPU_FMT_DITHER_ENABLE, "on" }, { AMDGPU_FMT_DITHER_ENABLE, "on" },
}; };
int amdgpu_modeset_create_props(struct amdgpu_device *adev) int amdgpu_display_modeset_create_props(struct amdgpu_device *adev)
{ {
int sz; int sz;
...@@ -629,7 +646,7 @@ int amdgpu_modeset_create_props(struct amdgpu_device *adev) ...@@ -629,7 +646,7 @@ int amdgpu_modeset_create_props(struct amdgpu_device *adev)
return 0; return 0;
} }
void amdgpu_update_display_priority(struct amdgpu_device *adev) void amdgpu_display_update_priority(struct amdgpu_device *adev)
{ {
/* adjustment options for the display watermarks */ /* adjustment options for the display watermarks */
if ((amdgpu_disp_priority == 0) || (amdgpu_disp_priority > 2)) if ((amdgpu_disp_priority == 0) || (amdgpu_disp_priority > 2))
...@@ -639,7 +656,7 @@ void amdgpu_update_display_priority(struct amdgpu_device *adev) ...@@ -639,7 +656,7 @@ void amdgpu_update_display_priority(struct amdgpu_device *adev)
} }
static bool is_hdtv_mode(const struct drm_display_mode *mode) static bool amdgpu_display_is_hdtv_mode(const struct drm_display_mode *mode)
{ {
/* try and guess if this is a tv or a monitor */ /* try and guess if this is a tv or a monitor */
if ((mode->vdisplay == 480 && mode->hdisplay == 720) || /* 480p */ if ((mode->vdisplay == 480 && mode->hdisplay == 720) || /* 480p */
...@@ -651,9 +668,9 @@ static bool is_hdtv_mode(const struct drm_display_mode *mode) ...@@ -651,9 +668,9 @@ static bool is_hdtv_mode(const struct drm_display_mode *mode)
return false; return false;
} }
bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc, bool amdgpu_display_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode, const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode) struct drm_display_mode *adjusted_mode)
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct drm_encoder *encoder; struct drm_encoder *encoder;
...@@ -696,7 +713,7 @@ bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc, ...@@ -696,7 +713,7 @@ bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
((amdgpu_encoder->underscan_type == UNDERSCAN_ON) || ((amdgpu_encoder->underscan_type == UNDERSCAN_ON) ||
((amdgpu_encoder->underscan_type == UNDERSCAN_AUTO) && ((amdgpu_encoder->underscan_type == UNDERSCAN_AUTO) &&
drm_detect_hdmi_monitor(amdgpu_connector_edid(connector)) && drm_detect_hdmi_monitor(amdgpu_connector_edid(connector)) &&
is_hdtv_mode(mode)))) { amdgpu_display_is_hdtv_mode(mode)))) {
if (amdgpu_encoder->underscan_hborder != 0) if (amdgpu_encoder->underscan_hborder != 0)
amdgpu_crtc->h_border = amdgpu_encoder->underscan_hborder; amdgpu_crtc->h_border = amdgpu_encoder->underscan_hborder;
else else
...@@ -764,10 +781,10 @@ bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc, ...@@ -764,10 +781,10 @@ bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
* unknown small number of scanlines wrt. real scanout position. * unknown small number of scanlines wrt. real scanout position.
* *
*/ */
int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, int amdgpu_display_get_crtc_scanoutpos(struct drm_device *dev,
unsigned int flags, int *vpos, int *hpos, unsigned int pipe, unsigned int flags, int *vpos,
ktime_t *stime, ktime_t *etime, int *hpos, ktime_t *stime, ktime_t *etime,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
u32 vbl = 0, position = 0; u32 vbl = 0, position = 0;
int vbl_start, vbl_end, vtotal, ret = 0; int vbl_start, vbl_end, vtotal, ret = 0;
...@@ -859,7 +876,7 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, ...@@ -859,7 +876,7 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
return ret; return ret;
} }
int amdgpu_crtc_idx_to_irq_type(struct amdgpu_device *adev, int crtc) int amdgpu_display_crtc_idx_to_irq_type(struct amdgpu_device *adev, int crtc)
{ {
if (crtc < 0 || crtc >= adev->mode_info.num_crtc) if (crtc < 0 || crtc >= adev->mode_info.num_crtc)
return AMDGPU_CRTC_IRQ_NONE; return AMDGPU_CRTC_IRQ_NONE;
......
...@@ -23,9 +23,10 @@ ...@@ -23,9 +23,10 @@
#ifndef __AMDGPU_DISPLAY_H__ #ifndef __AMDGPU_DISPLAY_H__
#define __AMDGPU_DISPLAY_H__ #define __AMDGPU_DISPLAY_H__
uint32_t amdgpu_display_framebuffer_domains(struct amdgpu_device *adev);
struct drm_framebuffer * struct drm_framebuffer *
amdgpu_user_framebuffer_create(struct drm_device *dev, amdgpu_display_user_framebuffer_create(struct drm_device *dev,
struct drm_file *file_priv, struct drm_file *file_priv,
const struct drm_mode_fb_cmd2 *mode_cmd); const struct drm_mode_fb_cmd2 *mode_cmd);
#endif #endif
...@@ -265,9 +265,6 @@ enum amdgpu_pcie_gen { ...@@ -265,9 +265,6 @@ enum amdgpu_pcie_gen {
#define amdgpu_dpm_read_sensor(adev, idx, value, size) \ #define amdgpu_dpm_read_sensor(adev, idx, value, size) \
((adev)->powerplay.pp_funcs->read_sensor((adev)->powerplay.pp_handle, (idx), (value), (size))) ((adev)->powerplay.pp_funcs->read_sensor((adev)->powerplay.pp_handle, (idx), (value), (size)))
#define amdgpu_dpm_get_temperature(adev) \
((adev)->powerplay.pp_funcs->get_temperature((adev)->powerplay.pp_handle))
#define amdgpu_dpm_set_fan_control_mode(adev, m) \ #define amdgpu_dpm_set_fan_control_mode(adev, m) \
((adev)->powerplay.pp_funcs->set_fan_control_mode((adev)->powerplay.pp_handle, (m))) ((adev)->powerplay.pp_funcs->set_fan_control_mode((adev)->powerplay.pp_handle, (m)))
...@@ -328,8 +325,8 @@ enum amdgpu_pcie_gen { ...@@ -328,8 +325,8 @@ enum amdgpu_pcie_gen {
#define amdgpu_dpm_set_mclk_od(adev, value) \ #define amdgpu_dpm_set_mclk_od(adev, value) \
((adev)->powerplay.pp_funcs->set_mclk_od((adev)->powerplay.pp_handle, value)) ((adev)->powerplay.pp_funcs->set_mclk_od((adev)->powerplay.pp_handle, value))
#define amdgpu_dpm_dispatch_task(adev, task_id, input, output) \ #define amdgpu_dpm_dispatch_task(adev, task_id, user_state) \
((adev)->powerplay.pp_funcs->dispatch_tasks)((adev)->powerplay.pp_handle, (task_id), (input), (output)) ((adev)->powerplay.pp_funcs->dispatch_tasks)((adev)->powerplay.pp_handle, (task_id), (user_state))
#define amdgpu_dpm_check_state_equal(adev, cps, rps, equal) \ #define amdgpu_dpm_check_state_equal(adev, cps, rps, equal) \
((adev)->powerplay.pp_funcs->check_state_equal((adev)->powerplay.pp_handle, (cps), (rps), (equal))) ((adev)->powerplay.pp_funcs->check_state_equal((adev)->powerplay.pp_handle, (cps), (rps), (equal)))
...@@ -344,17 +341,9 @@ enum amdgpu_pcie_gen { ...@@ -344,17 +341,9 @@ enum amdgpu_pcie_gen {
((adev)->powerplay.pp_funcs->reset_power_profile_state(\ ((adev)->powerplay.pp_funcs->reset_power_profile_state(\
(adev)->powerplay.pp_handle, request)) (adev)->powerplay.pp_handle, request))
#define amdgpu_dpm_get_power_profile_state(adev, query) \ #define amdgpu_dpm_switch_power_profile(adev, type, en) \
((adev)->powerplay.pp_funcs->get_power_profile_state(\
(adev)->powerplay.pp_handle, query))
#define amdgpu_dpm_set_power_profile_state(adev, request) \
((adev)->powerplay.pp_funcs->set_power_profile_state(\
(adev)->powerplay.pp_handle, request))
#define amdgpu_dpm_switch_power_profile(adev, type) \
((adev)->powerplay.pp_funcs->switch_power_profile(\ ((adev)->powerplay.pp_funcs->switch_power_profile(\
(adev)->powerplay.pp_handle, type)) (adev)->powerplay.pp_handle, type, en))
#define amdgpu_dpm_set_clockgating_by_smu(adev, msg_id) \ #define amdgpu_dpm_set_clockgating_by_smu(adev, msg_id) \
((adev)->powerplay.pp_funcs->set_clockgating_by_smu(\ ((adev)->powerplay.pp_funcs->set_clockgating_by_smu(\
...@@ -366,6 +355,22 @@ enum amdgpu_pcie_gen { ...@@ -366,6 +355,22 @@ enum amdgpu_pcie_gen {
(adev)->powerplay.pp_handle, virtual_addr_low, \ (adev)->powerplay.pp_handle, virtual_addr_low, \
virtual_addr_hi, mc_addr_low, mc_addr_hi, size) virtual_addr_hi, mc_addr_low, mc_addr_hi, size)
#define amdgpu_dpm_get_power_profile_mode(adev, buf) \
((adev)->powerplay.pp_funcs->get_power_profile_mode(\
(adev)->powerplay.pp_handle, buf))
#define amdgpu_dpm_set_power_profile_mode(adev, parameter, size) \
((adev)->powerplay.pp_funcs->set_power_profile_mode(\
(adev)->powerplay.pp_handle, parameter, size))
#define amdgpu_dpm_odn_edit_dpm_table(adev, type, parameter, size) \
((adev)->powerplay.pp_funcs->odn_edit_dpm_table(\
(adev)->powerplay.pp_handle, type, parameter, size))
#define amdgpu_dpm_set_mmhub_powergating_by_smu(adev) \
((adev)->powerplay.pp_funcs->set_mmhub_powergating_by_smu( \
(adev)->powerplay.pp_handle))
struct amdgpu_dpm { struct amdgpu_dpm {
struct amdgpu_ps *ps; struct amdgpu_ps *ps;
/* number of valid power states */ /* number of valid power states */
......
...@@ -73,9 +73,11 @@ ...@@ -73,9 +73,11 @@
* - 3.21.0 - Add DRM_AMDGPU_FENCE_TO_HANDLE ioctl * - 3.21.0 - Add DRM_AMDGPU_FENCE_TO_HANDLE ioctl
* - 3.22.0 - Add DRM_AMDGPU_SCHED ioctl * - 3.22.0 - Add DRM_AMDGPU_SCHED ioctl
* - 3.23.0 - Add query for VRAM lost counter * - 3.23.0 - Add query for VRAM lost counter
* - 3.24.0 - Add high priority compute support for gfx9
* - 3.25.0 - Add support for sensor query info (stable pstate sclk/mclk).
*/ */
#define KMS_DRIVER_MAJOR 3 #define KMS_DRIVER_MAJOR 3
#define KMS_DRIVER_MINOR 23 #define KMS_DRIVER_MINOR 25
#define KMS_DRIVER_PATCHLEVEL 0 #define KMS_DRIVER_PATCHLEVEL 0
int amdgpu_vram_limit = 0; int amdgpu_vram_limit = 0;
...@@ -119,7 +121,7 @@ uint amdgpu_pg_mask = 0xffffffff; ...@@ -119,7 +121,7 @@ uint amdgpu_pg_mask = 0xffffffff;
uint amdgpu_sdma_phase_quantum = 32; uint amdgpu_sdma_phase_quantum = 32;
char *amdgpu_disable_cu = NULL; char *amdgpu_disable_cu = NULL;
char *amdgpu_virtual_display = NULL; char *amdgpu_virtual_display = NULL;
uint amdgpu_pp_feature_mask = 0xffffffff; uint amdgpu_pp_feature_mask = 0xffffbfff;
int amdgpu_ngg = 0; int amdgpu_ngg = 0;
int amdgpu_prim_buf_per_se = 0; int amdgpu_prim_buf_per_se = 0;
int amdgpu_pos_buf_per_se = 0; int amdgpu_pos_buf_per_se = 0;
...@@ -129,6 +131,7 @@ int amdgpu_job_hang_limit = 0; ...@@ -129,6 +131,7 @@ int amdgpu_job_hang_limit = 0;
int amdgpu_lbpw = -1; int amdgpu_lbpw = -1;
int amdgpu_compute_multipipe = -1; int amdgpu_compute_multipipe = -1;
int amdgpu_gpu_recovery = -1; /* auto */ int amdgpu_gpu_recovery = -1; /* auto */
int amdgpu_emu_mode = 0;
MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes"); MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes");
module_param_named(vramlimit, amdgpu_vram_limit, int, 0600); module_param_named(vramlimit, amdgpu_vram_limit, int, 0600);
...@@ -281,9 +284,12 @@ module_param_named(lbpw, amdgpu_lbpw, int, 0444); ...@@ -281,9 +284,12 @@ module_param_named(lbpw, amdgpu_lbpw, int, 0444);
MODULE_PARM_DESC(compute_multipipe, "Force compute queues to be spread across pipes (1 = enable, 0 = disable, -1 = auto)"); MODULE_PARM_DESC(compute_multipipe, "Force compute queues to be spread across pipes (1 = enable, 0 = disable, -1 = auto)");
module_param_named(compute_multipipe, amdgpu_compute_multipipe, int, 0444); module_param_named(compute_multipipe, amdgpu_compute_multipipe, int, 0444);
MODULE_PARM_DESC(gpu_recovery, "Enable GPU recovery mechanism, (1 = enable, 0 = disable, -1 = auto"); MODULE_PARM_DESC(gpu_recovery, "Enable GPU recovery mechanism, (1 = enable, 0 = disable, -1 = auto)");
module_param_named(gpu_recovery, amdgpu_gpu_recovery, int, 0444); module_param_named(gpu_recovery, amdgpu_gpu_recovery, int, 0444);
MODULE_PARM_DESC(emu_mode, "Emulation mode, (1 = enable, 0 = disable)");
module_param_named(emu_mode, amdgpu_emu_mode, int, 0444);
#ifdef CONFIG_DRM_AMDGPU_SI #ifdef CONFIG_DRM_AMDGPU_SI
#if defined(CONFIG_DRM_RADEON) || defined(CONFIG_DRM_RADEON_MODULE) #if defined(CONFIG_DRM_RADEON) || defined(CONFIG_DRM_RADEON_MODULE)
...@@ -576,6 +582,11 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, ...@@ -576,6 +582,11 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
struct drm_device *dev; struct drm_device *dev;
unsigned long flags = ent->driver_data; unsigned long flags = ent->driver_data;
int ret, retry = 0; int ret, retry = 0;
bool supports_atomic = false;
if (!amdgpu_virtual_display &&
amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK))
supports_atomic = true;
if ((flags & AMD_EXP_HW_SUPPORT) && !amdgpu_exp_hw_support) { if ((flags & AMD_EXP_HW_SUPPORT) && !amdgpu_exp_hw_support) {
DRM_INFO("This hardware requires experimental hardware support.\n" DRM_INFO("This hardware requires experimental hardware support.\n"
...@@ -596,6 +607,13 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, ...@@ -596,6 +607,13 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
if (ret) if (ret)
return ret; return ret;
/* warn the user if they mix atomic and non-atomic capable GPUs */
if ((kms_driver.driver_features & DRIVER_ATOMIC) && !supports_atomic)
DRM_ERROR("Mixing atomic and non-atomic capable GPUs!\n");
/* support atomic early so the atomic debugfs stuff gets created */
if (supports_atomic)
kms_driver.driver_features |= DRIVER_ATOMIC;
dev = drm_dev_alloc(&kms_driver, &pdev->dev); dev = drm_dev_alloc(&kms_driver, &pdev->dev);
if (IS_ERR(dev)) if (IS_ERR(dev))
return PTR_ERR(dev); return PTR_ERR(dev);
...@@ -833,8 +851,8 @@ amdgpu_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, ...@@ -833,8 +851,8 @@ amdgpu_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe,
ktime_t *stime, ktime_t *etime, ktime_t *stime, ktime_t *etime,
const struct drm_display_mode *mode) const struct drm_display_mode *mode)
{ {
return amdgpu_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos, return amdgpu_display_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos,
stime, etime, mode); stime, etime, mode);
} }
static struct drm_driver kms_driver = { static struct drm_driver kms_driver = {
...@@ -852,9 +870,6 @@ static struct drm_driver kms_driver = { ...@@ -852,9 +870,6 @@ static struct drm_driver kms_driver = {
.disable_vblank = amdgpu_disable_vblank_kms, .disable_vblank = amdgpu_disable_vblank_kms,
.get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos,
.get_scanout_position = amdgpu_get_crtc_scanout_position, .get_scanout_position = amdgpu_get_crtc_scanout_position,
.irq_preinstall = amdgpu_irq_preinstall,
.irq_postinstall = amdgpu_irq_postinstall,
.irq_uninstall = amdgpu_irq_uninstall,
.irq_handler = amdgpu_irq_handler, .irq_handler = amdgpu_irq_handler,
.ioctls = amdgpu_ioctls_kms, .ioctls = amdgpu_ioctls_kms,
.gem_free_object_unlocked = amdgpu_gem_object_free, .gem_free_object_unlocked = amdgpu_gem_object_free,
...@@ -867,9 +882,7 @@ static struct drm_driver kms_driver = { ...@@ -867,9 +882,7 @@ static struct drm_driver kms_driver = {
.prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle, .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_export = amdgpu_gem_prime_export, .gem_prime_export = amdgpu_gem_prime_export,
.gem_prime_import = drm_gem_prime_import, .gem_prime_import = amdgpu_gem_prime_import,
.gem_prime_pin = amdgpu_gem_prime_pin,
.gem_prime_unpin = amdgpu_gem_prime_unpin,
.gem_prime_res_obj = amdgpu_gem_prime_res_obj, .gem_prime_res_obj = amdgpu_gem_prime_res_obj,
.gem_prime_get_sg_table = amdgpu_gem_prime_get_sg_table, .gem_prime_get_sg_table = amdgpu_gem_prime_get_sg_table,
.gem_prime_import_sg_table = amdgpu_gem_prime_import_sg_table, .gem_prime_import_sg_table = amdgpu_gem_prime_import_sg_table,
......
...@@ -38,6 +38,8 @@ ...@@ -38,6 +38,8 @@
#include <linux/vga_switcheroo.h> #include <linux/vga_switcheroo.h>
#include "amdgpu_display.h"
/* object hierarchy - /* object hierarchy -
this contains a helper + a amdgpu fb this contains a helper + a amdgpu fb
the helper contains a pointer to amdgpu framebuffer baseclass. the helper contains a pointer to amdgpu framebuffer baseclass.
...@@ -124,7 +126,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev, ...@@ -124,7 +126,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
struct drm_gem_object *gobj = NULL; struct drm_gem_object *gobj = NULL;
struct amdgpu_bo *abo = NULL; struct amdgpu_bo *abo = NULL;
bool fb_tiled = false; /* useful for testing */ bool fb_tiled = false; /* useful for testing */
u32 tiling_flags = 0; u32 tiling_flags = 0, domain;
int ret; int ret;
int aligned_size, size; int aligned_size, size;
int height = mode_cmd->height; int height = mode_cmd->height;
...@@ -135,12 +137,12 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev, ...@@ -135,12 +137,12 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
/* need to align pitch with crtc limits */ /* need to align pitch with crtc limits */
mode_cmd->pitches[0] = amdgpu_align_pitch(adev, mode_cmd->width, cpp, mode_cmd->pitches[0] = amdgpu_align_pitch(adev, mode_cmd->width, cpp,
fb_tiled); fb_tiled);
domain = amdgpu_display_framebuffer_domains(adev);
height = ALIGN(mode_cmd->height, 8); height = ALIGN(mode_cmd->height, 8);
size = mode_cmd->pitches[0] * height; size = mode_cmd->pitches[0] * height;
aligned_size = ALIGN(size, PAGE_SIZE); aligned_size = ALIGN(size, PAGE_SIZE);
ret = amdgpu_gem_object_create(adev, aligned_size, 0, ret = amdgpu_gem_object_create(adev, aligned_size, 0, domain,
AMDGPU_GEM_DOMAIN_VRAM,
AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS |
AMDGPU_GEM_CREATE_VRAM_CLEARED, AMDGPU_GEM_CREATE_VRAM_CLEARED,
...@@ -166,7 +168,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev, ...@@ -166,7 +168,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
} }
ret = amdgpu_bo_pin(abo, AMDGPU_GEM_DOMAIN_VRAM, NULL); ret = amdgpu_bo_pin(abo, domain, NULL);
if (ret) { if (ret) {
amdgpu_bo_unreserve(abo); amdgpu_bo_unreserve(abo);
goto out_unref; goto out_unref;
...@@ -225,7 +227,8 @@ static int amdgpufb_create(struct drm_fb_helper *helper, ...@@ -225,7 +227,8 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
info->par = rfbdev; info->par = rfbdev;
info->skip_vt_switch = true; info->skip_vt_switch = true;
ret = amdgpu_framebuffer_init(adev->ddev, &rfbdev->rfb, &mode_cmd, gobj); ret = amdgpu_display_framebuffer_init(adev->ddev, &rfbdev->rfb,
&mode_cmd, gobj);
if (ret) { if (ret) {
DRM_ERROR("failed to initialize framebuffer %d\n", ret); DRM_ERROR("failed to initialize framebuffer %d\n", ret);
goto out; goto out;
...@@ -242,8 +245,8 @@ static int amdgpufb_create(struct drm_fb_helper *helper, ...@@ -242,8 +245,8 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
info->fbops = &amdgpufb_ops; info->fbops = &amdgpufb_ops;
tmp = amdgpu_bo_gpu_offset(abo) - adev->mc.vram_start; tmp = amdgpu_bo_gpu_offset(abo) - adev->gmc.vram_start;
info->fix.smem_start = adev->mc.aper_base + tmp; info->fix.smem_start = adev->gmc.aper_base + tmp;
info->fix.smem_len = amdgpu_bo_size(abo); info->fix.smem_len = amdgpu_bo_size(abo);
info->screen_base = amdgpu_bo_kptr(abo); info->screen_base = amdgpu_bo_kptr(abo);
info->screen_size = amdgpu_bo_size(abo); info->screen_size = amdgpu_bo_size(abo);
...@@ -252,7 +255,7 @@ static int amdgpufb_create(struct drm_fb_helper *helper, ...@@ -252,7 +255,7 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
/* setup aperture base/size for vesafb takeover */ /* setup aperture base/size for vesafb takeover */
info->apertures->ranges[0].base = adev->ddev->mode_config.fb_base; info->apertures->ranges[0].base = adev->ddev->mode_config.fb_base;
info->apertures->ranges[0].size = adev->mc.aper_size; info->apertures->ranges[0].size = adev->gmc.aper_size;
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
...@@ -262,7 +265,7 @@ static int amdgpufb_create(struct drm_fb_helper *helper, ...@@ -262,7 +265,7 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
} }
DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start); DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start);
DRM_INFO("vram apper at 0x%lX\n", (unsigned long)adev->mc.aper_base); DRM_INFO("vram apper at 0x%lX\n", (unsigned long)adev->gmc.aper_base);
DRM_INFO("size %lu\n", (unsigned long)amdgpu_bo_size(abo)); DRM_INFO("size %lu\n", (unsigned long)amdgpu_bo_size(abo));
DRM_INFO("fb depth is %d\n", fb->format->depth); DRM_INFO("fb depth is %d\n", fb->format->depth);
DRM_INFO(" pitch is %d\n", fb->pitches[0]); DRM_INFO(" pitch is %d\n", fb->pitches[0]);
...@@ -319,7 +322,7 @@ int amdgpu_fbdev_init(struct amdgpu_device *adev) ...@@ -319,7 +322,7 @@ int amdgpu_fbdev_init(struct amdgpu_device *adev)
return 0; return 0;
/* select 8 bpp console on low vram cards */ /* select 8 bpp console on low vram cards */
if (adev->mc.real_vram_size <= (32*1024*1024)) if (adev->gmc.real_vram_size <= (32*1024*1024))
bpp_sel = 8; bpp_sel = 8;
rfbdev = kzalloc(sizeof(struct amdgpu_fbdev), GFP_KERNEL); rfbdev = kzalloc(sizeof(struct amdgpu_fbdev), GFP_KERNEL);
......
...@@ -68,17 +68,15 @@ ...@@ -68,17 +68,15 @@
*/ */
static int amdgpu_gart_dummy_page_init(struct amdgpu_device *adev) static int amdgpu_gart_dummy_page_init(struct amdgpu_device *adev)
{ {
if (adev->dummy_page.page) struct page *dummy_page = adev->mman.bdev.glob->dummy_read_page;
if (adev->dummy_page_addr)
return 0; return 0;
adev->dummy_page.page = alloc_page(GFP_DMA32 | GFP_KERNEL | __GFP_ZERO); adev->dummy_page_addr = pci_map_page(adev->pdev, dummy_page, 0,
if (adev->dummy_page.page == NULL) PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
return -ENOMEM; if (pci_dma_mapping_error(adev->pdev, adev->dummy_page_addr)) {
adev->dummy_page.addr = pci_map_page(adev->pdev, adev->dummy_page.page,
0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
if (pci_dma_mapping_error(adev->pdev, adev->dummy_page.addr)) {
dev_err(&adev->pdev->dev, "Failed to DMA MAP the dummy page\n"); dev_err(&adev->pdev->dev, "Failed to DMA MAP the dummy page\n");
__free_page(adev->dummy_page.page); adev->dummy_page_addr = 0;
adev->dummy_page.page = NULL;
return -ENOMEM; return -ENOMEM;
} }
return 0; return 0;
...@@ -93,12 +91,11 @@ static int amdgpu_gart_dummy_page_init(struct amdgpu_device *adev) ...@@ -93,12 +91,11 @@ static int amdgpu_gart_dummy_page_init(struct amdgpu_device *adev)
*/ */
static void amdgpu_gart_dummy_page_fini(struct amdgpu_device *adev) static void amdgpu_gart_dummy_page_fini(struct amdgpu_device *adev)
{ {
if (adev->dummy_page.page == NULL) if (!adev->dummy_page_addr)
return; return;
pci_unmap_page(adev->pdev, adev->dummy_page.addr, pci_unmap_page(adev->pdev, adev->dummy_page_addr,
PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
__free_page(adev->dummy_page.page); adev->dummy_page_addr = 0;
adev->dummy_page.page = NULL;
} }
/** /**
...@@ -116,11 +113,12 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev) ...@@ -116,11 +113,12 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev)
int r; int r;
if (adev->gart.robj == NULL) { if (adev->gart.robj == NULL) {
r = amdgpu_bo_create(adev, adev->gart.table_size, r = amdgpu_bo_create(adev, adev->gart.table_size, PAGE_SIZE,
PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, AMDGPU_GEM_DOMAIN_VRAM,
AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS,
NULL, NULL, 0, &adev->gart.robj); ttm_bo_type_kernel, NULL,
&adev->gart.robj);
if (r) { if (r) {
return r; return r;
} }
...@@ -236,18 +234,19 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset, ...@@ -236,18 +234,19 @@ int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
#ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS
adev->gart.pages[p] = NULL; adev->gart.pages[p] = NULL;
#endif #endif
page_base = adev->dummy_page.addr; page_base = adev->dummy_page_addr;
if (!adev->gart.ptr) if (!adev->gart.ptr)
continue; continue;
for (j = 0; j < (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); j++, t++) { for (j = 0; j < (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); j++, t++) {
amdgpu_gart_set_pte_pde(adev, adev->gart.ptr, amdgpu_gmc_set_pte_pde(adev, adev->gart.ptr,
t, page_base, flags); t, page_base, flags);
page_base += AMDGPU_GPU_PAGE_SIZE; page_base += AMDGPU_GPU_PAGE_SIZE;
} }
} }
mb(); mb();
amdgpu_gart_flush_gpu_tlb(adev, 0); amdgpu_asic_flush_hdp(adev, NULL);
amdgpu_gmc_flush_gpu_tlb(adev, 0);
return 0; return 0;
} }
...@@ -279,7 +278,7 @@ int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset, ...@@ -279,7 +278,7 @@ int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
for (i = 0; i < pages; i++) { for (i = 0; i < pages; i++) {
page_base = dma_addr[i]; page_base = dma_addr[i];
for (j = 0; j < (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); j++, t++) { for (j = 0; j < (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); j++, t++) {
amdgpu_gart_set_pte_pde(adev, dst, t, page_base, flags); amdgpu_gmc_set_pte_pde(adev, dst, t, page_base, flags);
page_base += AMDGPU_GPU_PAGE_SIZE; page_base += AMDGPU_GPU_PAGE_SIZE;
} }
} }
...@@ -317,7 +316,7 @@ int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset, ...@@ -317,7 +316,7 @@ int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
t = offset / AMDGPU_GPU_PAGE_SIZE; t = offset / AMDGPU_GPU_PAGE_SIZE;
p = t / (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); p = t / (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE);
for (i = 0; i < pages; i++, p++) for (i = 0; i < pages; i++, p++)
adev->gart.pages[p] = pagelist[i]; adev->gart.pages[p] = pagelist ? pagelist[i] : NULL;
#endif #endif
if (!adev->gart.ptr) if (!adev->gart.ptr)
...@@ -329,7 +328,8 @@ int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset, ...@@ -329,7 +328,8 @@ int amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
return r; return r;
mb(); mb();
amdgpu_gart_flush_gpu_tlb(adev, 0); amdgpu_asic_flush_hdp(adev, NULL);
amdgpu_gmc_flush_gpu_tlb(adev, 0);
return 0; return 0;
} }
...@@ -345,7 +345,7 @@ int amdgpu_gart_init(struct amdgpu_device *adev) ...@@ -345,7 +345,7 @@ int amdgpu_gart_init(struct amdgpu_device *adev)
{ {
int r; int r;
if (adev->dummy_page.page) if (adev->dummy_page_addr)
return 0; return 0;
/* We need PAGE_SIZE >= AMDGPU_GPU_PAGE_SIZE */ /* We need PAGE_SIZE >= AMDGPU_GPU_PAGE_SIZE */
...@@ -357,8 +357,8 @@ int amdgpu_gart_init(struct amdgpu_device *adev) ...@@ -357,8 +357,8 @@ int amdgpu_gart_init(struct amdgpu_device *adev)
if (r) if (r)
return r; return r;
/* Compute table size */ /* Compute table size */
adev->gart.num_cpu_pages = adev->mc.gart_size / PAGE_SIZE; adev->gart.num_cpu_pages = adev->gmc.gart_size / PAGE_SIZE;
adev->gart.num_gpu_pages = adev->mc.gart_size / AMDGPU_GPU_PAGE_SIZE; adev->gart.num_gpu_pages = adev->gmc.gart_size / AMDGPU_GPU_PAGE_SIZE;
DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n", DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n",
adev->gart.num_cpu_pages, adev->gart.num_gpu_pages); adev->gart.num_cpu_pages, adev->gart.num_gpu_pages);
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
*/ */
struct amdgpu_device; struct amdgpu_device;
struct amdgpu_bo; struct amdgpu_bo;
struct amdgpu_gart_funcs;
#define AMDGPU_GPU_PAGE_SIZE 4096 #define AMDGPU_GPU_PAGE_SIZE 4096
#define AMDGPU_GPU_PAGE_MASK (AMDGPU_GPU_PAGE_SIZE - 1) #define AMDGPU_GPU_PAGE_MASK (AMDGPU_GPU_PAGE_SIZE - 1)
...@@ -52,8 +51,6 @@ struct amdgpu_gart { ...@@ -52,8 +51,6 @@ struct amdgpu_gart {
/* Asic default pte flags */ /* Asic default pte flags */
uint64_t gart_pte_flags; uint64_t gart_pte_flags;
const struct amdgpu_gart_funcs *gart_funcs;
}; };
int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev); int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev);
......
此差异已折叠。
...@@ -56,7 +56,7 @@ static int amdgpu_gtt_mgr_init(struct ttm_mem_type_manager *man, ...@@ -56,7 +56,7 @@ static int amdgpu_gtt_mgr_init(struct ttm_mem_type_manager *man,
return -ENOMEM; return -ENOMEM;
start = AMDGPU_GTT_MAX_TRANSFER_SIZE * AMDGPU_GTT_NUM_TRANSFER_WINDOWS; start = AMDGPU_GTT_MAX_TRANSFER_SIZE * AMDGPU_GTT_NUM_TRANSFER_WINDOWS;
size = (adev->mc.gart_size >> PAGE_SHIFT) - start; size = (adev->gmc.gart_size >> PAGE_SHIFT) - start;
drm_mm_init(&mgr->mm, start, size); drm_mm_init(&mgr->mm, start, size);
spin_lock_init(&mgr->lock); spin_lock_init(&mgr->lock);
atomic64_set(&mgr->available, p_size); atomic64_set(&mgr->available, p_size);
...@@ -75,7 +75,7 @@ static int amdgpu_gtt_mgr_init(struct ttm_mem_type_manager *man, ...@@ -75,7 +75,7 @@ static int amdgpu_gtt_mgr_init(struct ttm_mem_type_manager *man,
static int amdgpu_gtt_mgr_fini(struct ttm_mem_type_manager *man) static int amdgpu_gtt_mgr_fini(struct ttm_mem_type_manager *man)
{ {
struct amdgpu_gtt_mgr *mgr = man->priv; struct amdgpu_gtt_mgr *mgr = man->priv;
spin_lock(&mgr->lock);
drm_mm_takedown(&mgr->mm); drm_mm_takedown(&mgr->mm);
spin_unlock(&mgr->lock); spin_unlock(&mgr->lock);
kfree(mgr); kfree(mgr);
......
...@@ -78,9 +78,7 @@ struct amdgpu_irq { ...@@ -78,9 +78,7 @@ struct amdgpu_irq {
uint32_t srbm_soft_reset; uint32_t srbm_soft_reset;
}; };
void amdgpu_irq_preinstall(struct drm_device *dev); void amdgpu_irq_disable_all(struct amdgpu_device *adev);
int amdgpu_irq_postinstall(struct drm_device *dev);
void amdgpu_irq_uninstall(struct drm_device *dev);
irqreturn_t amdgpu_irq_handler(int irq, void *arg); irqreturn_t amdgpu_irq_handler(int irq, void *arg);
int amdgpu_irq_init(struct amdgpu_device *adev); int amdgpu_irq_init(struct amdgpu_device *adev);
......
此差异已折叠。
...@@ -50,6 +50,7 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, ...@@ -50,6 +50,7 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync, struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync,
struct amdgpu_ring *ring); struct amdgpu_ring *ring);
struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync, bool *explicit); struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync, bool *explicit);
int amdgpu_sync_clone(struct amdgpu_sync *source, struct amdgpu_sync *clone);
int amdgpu_sync_wait(struct amdgpu_sync *sync, bool intr); int amdgpu_sync_wait(struct amdgpu_sync *sync, bool intr);
void amdgpu_sync_free(struct amdgpu_sync *sync); void amdgpu_sync_free(struct amdgpu_sync *sync);
int amdgpu_sync_init(void); int amdgpu_sync_init(void);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册