drm-misc-next for 5.14:

UAPI Changes:
 
  * Use DRM driver names for fbdev
 
 Cross-subsystem Changes:
 
 Core Changes:
 
  * Fix leaked DMA handles
 
  * Improve documentation around DRM_CLIENT_CAP_*
 
  * Cleanups
 
  * dp_mst: Use kHz as link-rate unit during init
 
  * fourcc: Remove drm_gem_format_name() and drm_format_name_buf
 
  * gem-cma: Fix mmap for buffers with write combining
 
  * ttm: Don't override pre-set vm_ops; ttm_bo_mmap() removal and cleanups
 
 Driver Changes:
 
  * drm/amdgpu: Fix hot unplug during suspend; Implement mmap as GEM object
    function; Use %p4cc format-string modifier; Cleanups
 
  * drm/bridge: Cdns: Fix PM reference leak, Cleanups; Lt8912b: Fix Coccinelle
    warnings; Fix Kconfig dependencies; Fixes and cleanups
 
  * drm/hisilicon/kirin: Cleanups
 
  * drm/nouveau: Implement mmap as GEM object function
 
  * drm/radeon: Implement mmap as GEM object function
 
  * drm/rockchip: Remove generic drivers during init; Add scaling for RK3036
    win1; Fix missing registers for RK3066 and 3188; Add alpha support for
    RK3036, RK3066, RK3126 and RK3188; Fixes and cleanups
 
  * drm/simpledrm: Use %p4cc: format-string modifier
 
  * drm/vmwgfx: Cleanups
 
  * fbdev/matrox: Use modern module_init()
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCAAdFiEEchf7rIzpz2NEoWjlaA3BHVMLeiMFAmC2S24ACgkQaA3BHVML
 eiPiSwgAuWKdl4QNoMquYwORm96NHVQaWxtrLzc7QanEKz4eyMJ7MQlC1ifX0101
 5qEkCx4it3wZPmMyN1GZtqwvu38zyXqPTwqA5f6Llb7xNiYxc2e69xT/K/zm3Qs0
 sSC7pUeQKtVfye9eciOF9n/TMfnFqsePCUUg7QUqv/V/tb43dm5OVo6bDVzGKlNY
 wmlmt3vfdxMWnFVrB3qh/3Um3KAs+lLiMnMX33hqbDkGXeI0rBAHC4MAkcOdWZzl
 CFIjKfrc5aQUJXFBA2t352LGncgC4TwgkA4Ajr+YIcDcmzJLIZP/Irt8CwR6aYZl
 37ZN45vJ7OZVpupyVr3C/cYEu0KhAg==
 =vdZ6
 -----END PGP SIGNATURE-----

Merge tag 'drm-misc-next-2021-06-01' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

drm-misc-next for 5.14:

UAPI Changes:

 * Use DRM driver names for fbdev

Cross-subsystem Changes:

Core Changes:

 * Fix leaked DMA handles

 * Improve documentation around DRM_CLIENT_CAP_*

 * Cleanups

 * dp_mst: Use kHz as link-rate unit during init

 * fourcc: Remove drm_gem_format_name() and drm_format_name_buf

 * gem-cma: Fix mmap for buffers with write combining

 * ttm: Don't override pre-set vm_ops; ttm_bo_mmap() removal and cleanups

Driver Changes:

 * drm/amdgpu: Fix hot unplug during suspend; Implement mmap as GEM object
   function; Use %p4cc format-string modifier; Cleanups

 * drm/bridge: Cdns: Fix PM reference leak, Cleanups; Lt8912b: Fix Coccinelle
   warnings; Fix Kconfig dependencies; Fixes and cleanups

 * drm/hisilicon/kirin: Cleanups

 * drm/nouveau: Implement mmap as GEM object function

 * drm/radeon: Implement mmap as GEM object function

 * drm/rockchip: Remove generic drivers during init; Add scaling for RK3036
   win1; Fix missing registers for RK3066 and 3188; Add alpha support for
   RK3036, RK3066, RK3126 and RK3188; Fixes and cleanups

 * drm/simpledrm: Use %p4cc: format-string modifier

 * drm/vmwgfx: Cleanups

 * fbdev/matrox: Use modern module_init()

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/YLZOKiYE6XFmE/MH@linux-uq9g.fritz.box
This commit is contained in:
Dave Airlie 2021-06-02 12:06:43 +10:00
commit 43ed3c6c78
149 changed files with 1810 additions and 946 deletions

View File

@ -11,7 +11,9 @@ maintainers:
properties:
compatible:
const: brcm,bcm2835-vec
enum:
- brcm,bcm2711-vec
- brcm,bcm2835-vec
reg:
maxItems: 1

View File

@ -0,0 +1,82 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/bridge/google,cros-ec-anx7688.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ChromeOS EC ANX7688 HDMI to DP Converter through Type-C Port
maintainers:
- Nicolas Boichat <drinkcat@chromium.org>
- Enric Balletbo i Serra <enric.balletbo@collabora.com>
description: |
ChromeOS EC ANX7688 is a display bridge that converts HDMI 2.0 to
DisplayPort 1.3 Ultra-HDi (4096x2160p60). It is an Analogix ANX7688 chip
which is connected to and operated by the ChromeOS Embedded Controller
(See google,cros-ec.yaml). It is accessed using I2C tunneling through
the EC and therefore its node should be a child of an EC I2C tunnel node
(See google,cros-ec-i2c-tunnel.yaml).
properties:
compatible:
const: google,cros-ec-anx7688
reg:
maxItems: 1
description: I2C address of the device.
ports:
$ref: /schemas/graph.yaml#/properties/ports
properties:
port@0:
$ref: /schemas/graph.yaml#/properties/port
description: Video port for HDMI input.
port@1:
$ref: /schemas/graph.yaml#/properties/port
description: USB Type-c connector.
required:
- port@0
- port@1
required:
- compatible
- reg
- ports
additionalProperties: false
examples:
- |
i2c_tunnel_b: i2c-tunnel1 {
compatible = "google,cros-ec-i2c-tunnel";
google,remote-bus = <1>;
#address-cells = <1>;
#size-cells = <0>;
anx7688: anx7688@2c {
compatible = "google,cros-ec-anx7688";
reg = <0x2c>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
anx7688_in: endpoint {
remote-endpoint = <&hdmi0_out>;
};
};
port@1 {
reg = <1>;
anx7688_out: endpoint {
remote-endpoint = <&typec_connector>;
};
};
};
};
};

View File

@ -1,54 +0,0 @@
* Faraday TV Encoder TVE200
Required properties:
- compatible: must be one of:
"faraday,tve200"
"cortina,gemini-tvc", "faraday,tve200"
- reg: base address and size of the control registers block
- interrupts: contains an interrupt specifier for the interrupt
line from the TVE200
- clock-names: should contain "PCLK" for the clock line clocking the
silicon and "TVE" for the 27MHz clock to the video driver
- clocks: contains phandle and clock specifier pairs for the entries
in the clock-names property. See
Documentation/devicetree/bindings/clock/clock-bindings.txt
Optional properties:
- resets: contains the reset line phandle for the block
Required sub-nodes:
- port: describes LCD panel signals, following the common binding
for video transmitter interfaces; see
Documentation/devicetree/bindings/media/video-interfaces.txt
This port should have the properties:
reg = <0>;
It should have one endpoint connected to a remote endpoint where
the display is connected.
Example:
display-controller@6a000000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "faraday,tve200";
reg = <0x6a000000 0x1000>;
interrupts = <13 IRQ_TYPE_EDGE_RISING>;
resets = <&syscon GEMINI_RESET_TVC>;
clocks = <&syscon GEMINI_CLK_GATE_TVC>,
<&syscon GEMINI_CLK_TVC>;
clock-names = "PCLK", "TVE";
port@0 {
reg = <0>;
display_out: endpoint {
remote-endpoint = <&panel_in>;
};
};
};

View File

@ -0,0 +1,68 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/display/faraday,tve200.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Faraday TV Encoder TVE200
maintainers:
- Linus Walleij <linus.walleij@linaro.org>
properties:
compatible:
oneOf:
- const: faraday,tve200
- items:
- const: cortina,gemini-tvc
- const: faraday,tve200
reg:
maxItems: 1
interrupts:
minItems: 1
clock-names:
items:
- const: PCLK
- const: TVE
clocks:
minItems: 2
resets:
minItems: 1
port:
$ref: /schemas/graph.yaml#/properties/port
required:
- compatible
- reg
- interrupts
- clock-names
- clocks
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/cortina,gemini-clock.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/reset/cortina,gemini-reset.h>
display-controller@6a000000 {
compatible = "faraday,tve200";
reg = <0x6a000000 0x1000>;
interrupts = <13 IRQ_TYPE_EDGE_RISING>;
resets = <&syscon GEMINI_RESET_TVC>;
clocks = <&syscon GEMINI_CLK_GATE_TVC>,
<&syscon GEMINI_CLK_TVC>;
clock-names = "PCLK", "TVE";
port {
display_out: endpoint {
remote-endpoint = <&panel_in>;
};
};
};

View File

@ -99,7 +99,6 @@ config DRM_FBDEV_EMULATION
bool "Enable legacy fbdev support for your modesetting driver"
depends on DRM
select DRM_KMS_HELPER
select DRM_KMS_FB_HELPER
select FB
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA

View File

@ -1078,7 +1078,7 @@ struct amdgpu_device {
uint32_t ras_hw_enabled;
uint32_t ras_enabled;
bool in_pci_err_recovery;
bool no_hw_access;
struct pci_saved_state *pci_state;
struct amdgpu_reset_control *reset_cntl;
@ -1101,7 +1101,9 @@ static inline struct amdgpu_device *amdgpu_ttm_adev(struct ttm_device *bdev)
int amdgpu_device_init(struct amdgpu_device *adev,
uint32_t flags);
void amdgpu_device_fini(struct amdgpu_device *adev);
void amdgpu_device_fini_hw(struct amdgpu_device *adev);
void amdgpu_device_fini_sw(struct amdgpu_device *adev);
int amdgpu_gpu_wait_for_idle(struct amdgpu_device *adev);
void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
@ -1321,6 +1323,8 @@ void amdgpu_driver_lastclose_kms(struct drm_device *dev);
int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv);
void amdgpu_driver_postclose_kms(struct drm_device *dev,
struct drm_file *file_priv);
void amdgpu_driver_release_kms(struct drm_device *dev);
int amdgpu_device_ip_suspend(struct amdgpu_device *adev);
int amdgpu_device_suspend(struct drm_device *dev, bool fbcon);
int amdgpu_device_resume(struct drm_device *dev, bool fbcon);

View File

@ -170,7 +170,7 @@ void amdgpu_amdkfd_device_init(struct amdgpu_device *adev)
}
}
void amdgpu_amdkfd_device_fini(struct amdgpu_device *adev)
void amdgpu_amdkfd_device_fini_sw(struct amdgpu_device *adev)
{
if (adev->kfd.dev) {
kgd2kfd_device_exit(adev->kfd.dev);

View File

@ -142,7 +142,7 @@ void amdgpu_amdkfd_interrupt(struct amdgpu_device *adev,
const void *ih_ring_entry);
void amdgpu_amdkfd_device_probe(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_sw(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);

View File

@ -1768,6 +1768,15 @@ static ssize_t amdgpu_atombios_get_vbios_version(struct device *dev,
static DEVICE_ATTR(vbios_version, 0444, amdgpu_atombios_get_vbios_version,
NULL);
static struct attribute *amdgpu_vbios_version_attrs[] = {
&dev_attr_vbios_version.attr,
NULL
};
const struct attribute_group amdgpu_vbios_version_attr_group = {
.attrs = amdgpu_vbios_version_attrs
};
/**
* amdgpu_atombios_fini - free the driver info and callbacks for atombios
*
@ -1787,7 +1796,6 @@ void amdgpu_atombios_fini(struct amdgpu_device *adev)
adev->mode_info.atom_context = NULL;
kfree(adev->mode_info.atom_card_info);
adev->mode_info.atom_card_info = NULL;
device_remove_file(adev->dev, &dev_attr_vbios_version);
}
/**
@ -1804,7 +1812,6 @@ int amdgpu_atombios_init(struct amdgpu_device *adev)
{
struct card_info *atom_card_info =
kzalloc(sizeof(struct card_info), GFP_KERNEL);
int ret;
if (!atom_card_info)
return -ENOMEM;
@ -1836,12 +1843,6 @@ int amdgpu_atombios_init(struct amdgpu_device *adev)
amdgpu_atombios_allocate_fb_scratch(adev);
}
ret = device_create_file(adev->dev, &dev_attr_vbios_version);
if (ret) {
DRM_ERROR("Failed to create device file for VBIOS version\n");
return ret;
}
return 0;
}

View File

@ -71,6 +71,8 @@
#include <drm/task_barrier.h>
#include <linux/pm_runtime.h>
#include <drm/drm_drv.h>
MODULE_FIRMWARE("amdgpu/vega10_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/vega12_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin");
@ -282,7 +284,10 @@ void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
unsigned long flags;
uint32_t hi = ~0;
uint64_t last;
int idx;
if (!drm_dev_enter(&adev->ddev, &idx))
return;
#ifdef CONFIG_64BIT
last = min(pos + size, adev->gmc.visible_vram_size);
@ -301,7 +306,7 @@ void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
}
if (count == size)
return;
goto exit;
pos += count;
buf += count / 4;
@ -324,6 +329,11 @@ void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
*buf++ = RREG32_NO_KIQ(mmMM_DATA);
}
spin_unlock_irqrestore(&adev->mmio_idx_lock, flags);
#ifdef CONFIG_64BIT
exit:
#endif
drm_dev_exit(idx);
}
/*
@ -333,7 +343,7 @@ void amdgpu_device_vram_access(struct amdgpu_device *adev, loff_t pos,
/* Check if hw access should be skipped because of hotplug or device error */
bool amdgpu_device_skip_hw_access(struct amdgpu_device *adev)
{
if (adev->in_pci_err_recovery)
if (adev->no_hw_access)
return true;
#ifdef CONFIG_LOCKDEP
@ -2574,34 +2584,26 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev)
return 0;
}
/**
* amdgpu_device_ip_fini - run fini for hardware IPs
*
* @adev: amdgpu_device pointer
*
* Main teardown pass for hardware IPs. The list of all the hardware
* IPs that make up the asic is walked and the hw_fini and sw_fini callbacks
* are run. hw_fini tears down the hardware associated with each IP
* and sw_fini tears down any software state associated with each IP.
* Returns 0 on success, negative error code on failure.
*/
static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
static int amdgpu_device_ip_fini_early(struct amdgpu_device *adev)
{
int i, r;
if (amdgpu_sriov_vf(adev) && adev->virt.ras_init_done)
amdgpu_virt_release_ras_err_handler_data(adev);
for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_blocks[i].version->funcs->early_fini)
continue;
amdgpu_ras_pre_fini(adev);
r = adev->ip_blocks[i].version->funcs->early_fini((void *)adev);
if (r) {
DRM_DEBUG("early_fini of IP block <%s> failed %d\n",
adev->ip_blocks[i].version->funcs->name, r);
}
}
if (adev->gmc.xgmi.num_physical_nodes > 1)
amdgpu_xgmi_remove_device(adev);
amdgpu_amdkfd_suspend(adev, false);
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
amdgpu_amdkfd_device_fini(adev);
/* need to disable SMC first */
for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_blocks[i].status.hw)
@ -2632,6 +2634,33 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
adev->ip_blocks[i].status.hw = false;
}
return 0;
}
/**
* amdgpu_device_ip_fini - run fini for hardware IPs
*
* @adev: amdgpu_device pointer
*
* Main teardown pass for hardware IPs. The list of all the hardware
* IPs that make up the asic is walked and the hw_fini and sw_fini callbacks
* are run. hw_fini tears down the hardware associated with each IP
* and sw_fini tears down any software state associated with each IP.
* Returns 0 on success, negative error code on failure.
*/
static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
{
int i, r;
if (amdgpu_sriov_vf(adev) && adev->virt.ras_init_done)
amdgpu_virt_release_ras_err_handler_data(adev);
amdgpu_ras_pre_fini(adev);
if (adev->gmc.xgmi.num_physical_nodes > 1)
amdgpu_xgmi_remove_device(adev);
amdgpu_amdkfd_device_fini_sw(adev);
for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
if (!adev->ip_blocks[i].status.sw)
@ -3251,7 +3280,6 @@ static const struct attribute *amdgpu_dev_attributes[] = {
NULL
};
/**
* amdgpu_device_init - initialize the driver
*
@ -3653,6 +3681,27 @@ failed_unmap:
return r;
}
static void amdgpu_device_unmap_mmio(struct amdgpu_device *adev)
{
/* Clear all CPU mappings pointing to this device */
unmap_mapping_range(adev->ddev.anon_inode->i_mapping, 0, 0, 1);
/* Unmap all mapped bars - Doorbell, registers and VRAM */
amdgpu_device_doorbell_fini(adev);
iounmap(adev->rmmio);
adev->rmmio = NULL;
if (adev->mman.aper_base_kaddr)
iounmap(adev->mman.aper_base_kaddr);
adev->mman.aper_base_kaddr = NULL;
/* Memory manager related */
if (!adev->gmc.xgmi.connected_to_cpu) {
arch_phys_wc_del(adev->gmc.vram_mtrr);
arch_io_free_memtype_wc(adev->gmc.aper_base, adev->gmc.aper_size);
}
}
/**
* amdgpu_device_fini - tear down the driver
*
@ -3661,15 +3710,13 @@ failed_unmap:
* Tear down the driver info (all asics).
* Called at driver shutdown.
*/
void amdgpu_device_fini(struct amdgpu_device *adev)
void amdgpu_device_fini_hw(struct amdgpu_device *adev)
{
dev_info(adev->dev, "amdgpu: finishing device.\n");
flush_delayed_work(&adev->delayed_init_work);
ttm_bo_lock_delayed_workqueue(&adev->mman.bdev);
adev->shutdown = true;
kfree(adev->pci_state);
/* make sure IB test finished before entering exclusive mode
* to avoid preemption on IB test
* */
@ -3686,11 +3733,29 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
else
drm_atomic_helper_shutdown(adev_to_drm(adev));
}
amdgpu_fence_driver_fini(adev);
amdgpu_fence_driver_fini_hw(adev);
if (adev->pm_sysfs_en)
amdgpu_pm_sysfs_fini(adev);
if (adev->ucode_sysfs_en)
amdgpu_ucode_sysfs_fini(adev);
sysfs_remove_files(&adev->dev->kobj, amdgpu_dev_attributes);
amdgpu_fbdev_fini(adev);
amdgpu_irq_fini_hw(adev);
amdgpu_device_ip_fini_early(adev);
amdgpu_gart_dummy_page_fini(adev);
amdgpu_device_unmap_mmio(adev);
}
void amdgpu_device_fini_sw(struct amdgpu_device *adev)
{
amdgpu_device_ip_fini(adev);
amdgpu_fence_driver_fini_sw(adev);
release_firmware(adev->firmware.gpu_info_fw);
adev->firmware.gpu_info_fw = NULL;
adev->accel_working = false;
@ -3712,18 +3777,14 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
}
if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
vga_client_register(adev->pdev, NULL, NULL, NULL);
iounmap(adev->rmmio);
adev->rmmio = NULL;
amdgpu_device_doorbell_fini(adev);
if (adev->ucode_sysfs_en)
amdgpu_ucode_sysfs_fini(adev);
sysfs_remove_files(&adev->dev->kobj, amdgpu_dev_attributes);
if (IS_ENABLED(CONFIG_PERF_EVENTS))
amdgpu_pmu_fini(adev);
if (adev->mman.discovery_bin)
amdgpu_discovery_fini(adev);
kfree(adev->pci_state);
}
@ -5291,9 +5352,9 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev)
set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
set_bit(AMDGPU_SKIP_HW_RESET, &reset_context.flags);
adev->in_pci_err_recovery = true;
adev->no_hw_access = true;
r = amdgpu_device_pre_asic_reset(adev, &reset_context);
adev->in_pci_err_recovery = false;
adev->no_hw_access = false;
if (r)
goto out;

View File

@ -1077,12 +1077,9 @@ int amdgpu_display_gem_fb_verify_and_init(
/* Verify that the modifier is supported. */
if (!drm_any_plane_has_format(dev, mode_cmd->pixel_format,
mode_cmd->modifier[0])) {
struct drm_format_name_buf format_name;
drm_dbg_kms(dev,
"unsupported pixel format %s / modifier 0x%llx\n",
drm_get_format_name(mode_cmd->pixel_format,
&format_name),
mode_cmd->modifier[0]);
"unsupported pixel format %p4cc / modifier 0x%llx\n",
&mode_cmd->pixel_format, mode_cmd->modifier[0]);
ret = -EINVAL;
goto err;

View File

@ -42,52 +42,6 @@
#include <linux/pci-p2pdma.h>
#include <linux/pm_runtime.h>
/**
* amdgpu_gem_prime_mmap - &drm_driver.gem_prime_mmap implementation
* @obj: GEM BO
* @vma: Virtual memory area
*
* Sets up a userspace mapping of the BO's memory in the given
* virtual memory area.
*
* Returns:
* 0 on success or a negative error code on failure.
*/
int amdgpu_gem_prime_mmap(struct drm_gem_object *obj,
struct vm_area_struct *vma)
{
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
unsigned asize = amdgpu_bo_size(bo);
int ret;
if (!vma->vm_file)
return -ENODEV;
if (adev == NULL)
return -ENODEV;
/* Check for valid size. */
if (asize < vma->vm_end - vma->vm_start)
return -EINVAL;
if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm) ||
(bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)) {
return -EPERM;
}
vma->vm_pgoff += amdgpu_bo_mmap_offset(bo) >> PAGE_SHIFT;
/* prime mmap does not need to check access, so allow here */
ret = drm_vma_node_allow(&obj->vma_node, vma->vm_file->private_data);
if (ret)
return ret;
ret = ttm_bo_mmap(vma->vm_file, vma, &adev->mman.bdev);
drm_vma_node_revoke(&obj->vma_node, vma->vm_file->private_data);
return ret;
}
static int
__dma_resv_make_exclusive(struct dma_resv *obj)
{

View File

@ -31,8 +31,6 @@ struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev,
struct dma_buf *dma_buf);
bool amdgpu_dmabuf_is_xgmi_accessible(struct amdgpu_device *adev,
struct amdgpu_bo *bo);
int amdgpu_gem_prime_mmap(struct drm_gem_object *obj,
struct vm_area_struct *vma);
extern const struct dma_buf_ops amdgpu_dmabuf_ops;

View File

@ -1313,14 +1313,16 @@ amdgpu_pci_remove(struct pci_dev *pdev)
{
struct drm_device *dev = pci_get_drvdata(pdev);
#ifdef MODULE
if (THIS_MODULE->state != MODULE_STATE_GOING)
#endif
DRM_ERROR("Hotplug removal is not supported\n");
drm_dev_unplug(dev);
amdgpu_driver_unload_kms(dev);
/*
* Flush any in flight DMA operations from device.
* Clear the Bus Master Enable bit and then wait on the PCIe Device
* StatusTransactions Pending bit.
*/
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
pci_wait_for_pending_transaction(pdev);
}
static void
@ -1555,6 +1557,10 @@ static int amdgpu_pmops_runtime_resume(struct device *dev)
if (!adev->runpm)
return -EINVAL;
/* Avoids registers access if device is physically gone */
if (!pci_device_is_present(adev->pdev))
adev->no_hw_access = true;
if (amdgpu_device_supports_px(drm_dev)) {
drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
@ -1689,7 +1695,7 @@ static const struct file_operations amdgpu_driver_kms_fops = {
.flush = amdgpu_flush,
.release = drm_release,
.unlocked_ioctl = amdgpu_drm_ioctl,
.mmap = amdgpu_mmap,
.mmap = drm_gem_mmap,
.poll = drm_poll,
.read = drm_read,
#ifdef CONFIG_COMPAT
@ -1751,11 +1757,12 @@ static const struct drm_driver amdgpu_kms_driver = {
.dumb_create = amdgpu_mode_dumb_create,
.dumb_map_offset = amdgpu_mode_dumb_mmap,
.fops = &amdgpu_driver_kms_fops,
.release = &amdgpu_driver_release_kms,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import = amdgpu_gem_prime_import,
.gem_prime_mmap = amdgpu_gem_prime_mmap,
.gem_prime_mmap = drm_gem_prime_mmap,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
@ -1772,6 +1779,18 @@ static struct pci_error_handlers amdgpu_pci_err_handler = {
.resume = amdgpu_pci_resume,
};
extern const struct attribute_group amdgpu_vram_mgr_attr_group;
extern const struct attribute_group amdgpu_gtt_mgr_attr_group;
extern const struct attribute_group amdgpu_vbios_version_attr_group;
static const struct attribute_group *amdgpu_sysfs_groups[] = {
&amdgpu_vram_mgr_attr_group,
&amdgpu_gtt_mgr_attr_group,
&amdgpu_vbios_version_attr_group,
NULL,
};
static struct pci_driver amdgpu_kms_pci_driver = {
.name = DRIVER_NAME,
.id_table = pciidlist,
@ -1780,6 +1799,7 @@ static struct pci_driver amdgpu_kms_pci_driver = {
.shutdown = amdgpu_pci_shutdown,
.driver.pm = &amdgpu_pm_ops,
.err_handler = &amdgpu_pci_err_handler,
.dev_groups = amdgpu_sysfs_groups,
};
static int __init amdgpu_init(void)

View File

@ -36,6 +36,7 @@
#include <linux/firmware.h>
#include <linux/pm_runtime.h>
#include <drm/drm_drv.h>
#include "amdgpu.h"
#include "amdgpu_trace.h"
@ -524,10 +525,9 @@ int amdgpu_fence_driver_init(struct amdgpu_device *adev)
*
* Tear down the fence driver for all possible rings (all asics).
*/
void amdgpu_fence_driver_fini(struct amdgpu_device *adev)
void amdgpu_fence_driver_fini_hw(struct amdgpu_device *adev)
{
unsigned i, j;
int r;
int i, r;
for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
struct amdgpu_ring *ring = adev->rings[i];
@ -536,16 +536,33 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev)
continue;
if (!ring->no_scheduler)
drm_sched_fini(&ring->sched);
r = amdgpu_fence_wait_empty(ring);
if (r) {
/* no need to trigger GPU reset as we are unloading */
/* You can't wait for HW to signal if it's gone */
if (!drm_dev_is_unplugged(&adev->ddev))
r = amdgpu_fence_wait_empty(ring);
else
r = -ENODEV;
/* no need to trigger GPU reset as we are unloading */
if (r)
amdgpu_fence_driver_force_completion(ring);
}
if (ring->fence_drv.irq_src)
amdgpu_irq_put(adev, ring->fence_drv.irq_src,
ring->fence_drv.irq_type);
del_timer_sync(&ring->fence_drv.fallback_timer);
}
}
void amdgpu_fence_driver_fini_sw(struct amdgpu_device *adev)
{
unsigned int i, j;
for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
struct amdgpu_ring *ring = adev->rings[i];
if (!ring || !ring->fence_drv.initialized)
continue;
for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j)
dma_fence_put(ring->fence_drv.fences[j]);
kfree(ring->fence_drv.fences);

View File

@ -92,7 +92,7 @@ static int amdgpu_gart_dummy_page_init(struct amdgpu_device *adev)
*
* Frees the dummy page used by the driver (all asics).
*/
static void amdgpu_gart_dummy_page_fini(struct amdgpu_device *adev)
void amdgpu_gart_dummy_page_fini(struct amdgpu_device *adev)
{
if (!adev->dummy_page_addr)
return;
@ -365,15 +365,3 @@ int amdgpu_gart_init(struct amdgpu_device *adev)
return 0;
}
/**
* amdgpu_gart_fini - tear down the driver info for managing the gart
*
* @adev: amdgpu_device pointer
*
* Tear down the gart driver info and free the dummy page (all asics).
*/
void amdgpu_gart_fini(struct amdgpu_device *adev)
{
amdgpu_gart_dummy_page_fini(adev);
}

View File

@ -57,7 +57,7 @@ void amdgpu_gart_table_vram_free(struct amdgpu_device *adev);
int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev);
void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev);
int amdgpu_gart_init(struct amdgpu_device *adev);
void amdgpu_gart_fini(struct amdgpu_device *adev);
void amdgpu_gart_dummy_page_fini(struct amdgpu_device *adev);
int amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
int pages);
int amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,

View File

@ -32,6 +32,7 @@
#include <linux/dma-buf.h>
#include <drm/amdgpu_drm.h>
#include <drm/drm_drv.h>
#include <drm/drm_gem_ttm_helper.h>
#include "amdgpu.h"
@ -41,6 +42,46 @@
static const struct drm_gem_object_funcs amdgpu_gem_object_funcs;
static vm_fault_t amdgpu_gem_fault(struct vm_fault *vmf)
{
struct ttm_buffer_object *bo = vmf->vma->vm_private_data;
struct drm_device *ddev = bo->base.dev;
vm_fault_t ret;
int idx;
ret = ttm_bo_vm_reserve(bo, vmf);
if (ret)
return ret;
if (drm_dev_enter(ddev, &idx)) {
ret = amdgpu_bo_fault_reserve_notify(bo);
if (ret) {
drm_dev_exit(idx);
goto unlock;
}
ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot,
TTM_BO_VM_NUM_PREFAULT, 1);
drm_dev_exit(idx);
} else {
ret = ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot);
}
if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
return ret;
unlock:
dma_resv_unlock(bo->base.resv);
return ret;
}
static const struct vm_operations_struct amdgpu_gem_vm_ops = {
.fault = amdgpu_gem_fault,
.open = ttm_bo_vm_open,
.close = ttm_bo_vm_close,
.access = ttm_bo_vm_access
};
static void amdgpu_gem_object_free(struct drm_gem_object *gobj)
{
struct amdgpu_bo *robj = gem_to_amdgpu_bo(gobj);
@ -205,6 +246,18 @@ out_unlock:
ttm_eu_backoff_reservation(&ticket, &list);
}
static int amdgpu_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
{
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm))
return -EPERM;
if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)
return -EPERM;
return drm_gem_ttm_mmap(obj, vma);
}
static const struct drm_gem_object_funcs amdgpu_gem_object_funcs = {
.free = amdgpu_gem_object_free,
.open = amdgpu_gem_object_open,
@ -212,6 +265,8 @@ static const struct drm_gem_object_funcs amdgpu_gem_object_funcs = {
.export = amdgpu_gem_prime_export,
.vmap = drm_gem_ttm_vmap,
.vunmap = drm_gem_ttm_vunmap,
.mmap = amdgpu_gem_object_mmap,
.vm_ops = &amdgpu_gem_vm_ops,
};
/*

View File

@ -31,6 +31,8 @@
#include "amdgpu_ras.h"
#include "amdgpu_xgmi.h"
#include <drm/drm_drv.h>
/**
* amdgpu_gmc_pdb0_alloc - allocate vram for pdb0
*
@ -151,6 +153,10 @@ int amdgpu_gmc_set_pte_pde(struct amdgpu_device *adev, void *cpu_pt_addr,
{
void __iomem *ptr = (void *)cpu_pt_addr;
uint64_t value;
int idx;
if (!drm_dev_enter(&adev->ddev, &idx))
return 0;
/*
* The following is for PTE only. GART does not have PDEs.
@ -158,6 +164,9 @@ int amdgpu_gmc_set_pte_pde(struct amdgpu_device *adev, void *cpu_pt_addr,
value = addr & 0x0000FFFFFFFFF000ULL;
value |= flags;
writeq(value, ptr + (gpu_page_idx * 8));
drm_dev_exit(idx);
return 0;
}

View File

@ -80,6 +80,16 @@ static DEVICE_ATTR(mem_info_gtt_total, S_IRUGO,
static DEVICE_ATTR(mem_info_gtt_used, S_IRUGO,
amdgpu_mem_info_gtt_used_show, NULL);
static struct attribute *amdgpu_gtt_mgr_attributes[] = {
&dev_attr_mem_info_gtt_total.attr,
&dev_attr_mem_info_gtt_used.attr,
NULL
};
const struct attribute_group amdgpu_gtt_mgr_attr_group = {
.attrs = amdgpu_gtt_mgr_attributes
};
/**
* amdgpu_gtt_mgr_has_gart_addr - Check if mem has address space
*
@ -263,7 +273,6 @@ int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t gtt_size)
struct amdgpu_gtt_mgr *mgr = &adev->mman.gtt_mgr;
struct ttm_resource_manager *man = &mgr->manager;
uint64_t start, size;
int ret;
man->use_tt = true;
man->func = &amdgpu_gtt_mgr_func;
@ -276,17 +285,6 @@ int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t gtt_size)
spin_lock_init(&mgr->lock);
atomic64_set(&mgr->available, gtt_size >> PAGE_SHIFT);
ret = device_create_file(adev->dev, &dev_attr_mem_info_gtt_total);
if (ret) {
DRM_ERROR("Failed to create device file mem_info_gtt_total\n");
return ret;
}
ret = device_create_file(adev->dev, &dev_attr_mem_info_gtt_used);
if (ret) {
DRM_ERROR("Failed to create device file mem_info_gtt_used\n");
return ret;
}
ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_TT, &mgr->manager);
ttm_resource_manager_set_used(man, true);
return 0;
@ -316,9 +314,6 @@ void amdgpu_gtt_mgr_fini(struct amdgpu_device *adev)
drm_mm_takedown(&mgr->mm);
spin_unlock(&mgr->lock);
device_remove_file(adev->dev, &dev_attr_mem_info_gtt_total);
device_remove_file(adev->dev, &dev_attr_mem_info_gtt_used);
ttm_resource_manager_cleanup(man);
ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_TT, NULL);
}

View File

@ -115,9 +115,11 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
*/
void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih)
{
if (!ih->ring)
return;
if (ih->use_bus_addr) {
if (!ih->ring)
return;
/* add 8 bytes for the rptr/wptr shadows and
* add them to the end of the ring allocation.

View File

@ -49,6 +49,7 @@
#include <drm/drm_irq.h>
#include <drm/drm_vblank.h>
#include <drm/amdgpu_drm.h>
#include <drm/drm_drv.h>
#include "amdgpu.h"
#include "amdgpu_ih.h"
#include "atom.h"
@ -348,6 +349,25 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
return 0;
}
void amdgpu_irq_fini_hw(struct amdgpu_device *adev)
{
if (adev->irq.installed) {
drm_irq_uninstall(&adev->ddev);
adev->irq.installed = false;
if (adev->irq.msi_enabled)
pci_free_irq_vectors(adev->pdev);
if (!amdgpu_device_has_dc_support(adev))
flush_work(&adev->hotplug_work);
}
amdgpu_ih_ring_fini(adev, &adev->irq.ih_soft);
amdgpu_ih_ring_fini(adev, &adev->irq.ih);
amdgpu_ih_ring_fini(adev, &adev->irq.ih1);
amdgpu_ih_ring_fini(adev, &adev->irq.ih2);
}
/**
* amdgpu_irq_fini - shut down interrupt handling
*
@ -357,19 +377,10 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
* functionality, shuts down vblank, hotplug and reset interrupt handling,
* turns off interrupts from all sources (all ASICs).
*/
void amdgpu_irq_fini(struct amdgpu_device *adev)
void amdgpu_irq_fini_sw(struct amdgpu_device *adev)
{
unsigned i, j;
if (adev->irq.installed) {
drm_irq_uninstall(adev_to_drm(adev));
adev->irq.installed = false;
if (adev->irq.msi_enabled)
pci_free_irq_vectors(adev->pdev);
if (!amdgpu_device_has_dc_support(adev))
flush_work(&adev->hotplug_work);
}
for (i = 0; i < AMDGPU_IRQ_CLIENTID_MAX; ++i) {
if (!adev->irq.client[i].sources)
continue;

View File

@ -103,7 +103,8 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev);
irqreturn_t amdgpu_irq_handler(int irq, void *arg);
int amdgpu_irq_init(struct amdgpu_device *adev);
void amdgpu_irq_fini(struct amdgpu_device *adev);
void amdgpu_irq_fini_sw(struct amdgpu_device *adev);
void amdgpu_irq_fini_hw(struct amdgpu_device *adev);
int amdgpu_irq_add_id(struct amdgpu_device *adev,
unsigned client_id, unsigned src_id,
struct amdgpu_irq_src *source);

View File

@ -25,6 +25,8 @@
#include <linux/wait.h>
#include <linux/sched.h>
#include <drm/drm_drv.h>
#include "amdgpu.h"
#include "amdgpu_trace.h"
@ -34,6 +36,15 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
struct amdgpu_job *job = to_amdgpu_job(s_job);
struct amdgpu_task_info ti;
struct amdgpu_device *adev = ring->adev;
int idx;
if (!drm_dev_enter(&adev->ddev, &idx)) {
DRM_INFO("%s - device unplugged skipping recovery on scheduler:%s",
__func__, s_job->sched->name);
/* Effectively the job is aborted as the device is gone */
return DRM_GPU_SCHED_STAT_ENODEV;
}
memset(&ti, 0, sizeof(struct amdgpu_task_info));
@ -41,7 +52,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
amdgpu_ring_soft_recovery(ring, job->vmid, s_job->s_fence->parent)) {
DRM_ERROR("ring %s timeout, but soft recovered\n",
s_job->sched->name);
return DRM_GPU_SCHED_STAT_NOMINAL;
goto exit;
}
amdgpu_vm_get_task_info(ring->adev, job->pasid, &ti);
@ -53,13 +64,15 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
if (amdgpu_device_should_recover_gpu(ring->adev)) {
amdgpu_device_gpu_recover(ring->adev, job);
return DRM_GPU_SCHED_STAT_NOMINAL;
} else {
drm_sched_suspend_timeout(&ring->sched);
if (amdgpu_sriov_vf(adev))
adev->virt.tdr_debug = true;
return DRM_GPU_SCHED_STAT_NOMINAL;
}
exit:
drm_dev_exit(idx);
return DRM_GPU_SCHED_STAT_NOMINAL;
}
int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,

View File

@ -28,6 +28,7 @@
#include "amdgpu.h"
#include <drm/amdgpu_drm.h>
#include <drm/drm_drv.h>
#include "amdgpu_uvd.h"
#include "amdgpu_vce.h"
#include "atom.h"
@ -92,7 +93,7 @@ void amdgpu_driver_unload_kms(struct drm_device *dev)
}
amdgpu_acpi_fini(adev);
amdgpu_device_fini(adev);
amdgpu_device_fini_hw(adev);
}
void amdgpu_register_gpu_instance(struct amdgpu_device *adev)
@ -1220,6 +1221,15 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
pm_runtime_put_autosuspend(dev->dev);
}
void amdgpu_driver_release_kms(struct drm_device *dev)
{
struct amdgpu_device *adev = drm_to_adev(dev);
amdgpu_device_fini_sw(adev);
pci_set_drvdata(adev->pdev, NULL);
}
/*
* VBlank related functions.
*/

View File

@ -1072,10 +1072,6 @@ int amdgpu_bo_init(struct amdgpu_device *adev)
void amdgpu_bo_fini(struct amdgpu_device *adev)
{
amdgpu_ttm_fini(adev);
if (!adev->gmc.xgmi.connected_to_cpu) {
arch_phys_wc_del(adev->gmc.vram_mtrr);
arch_io_free_memtype_wc(adev->gmc.aper_base, adev->gmc.aper_size);
}
}
/**

View File

@ -25,6 +25,7 @@
#include <linux/firmware.h>
#include <linux/dma-mapping.h>
#include <drm/drm_drv.h>
#include "amdgpu.h"
#include "amdgpu_psp.h"
@ -40,6 +41,8 @@
#include "amdgpu_securedisplay.h"
#include "amdgpu_atomfirmware.h"
#include <drm/drm_drv.h>
static int psp_sysfs_init(struct amdgpu_device *adev);
static void psp_sysfs_fini(struct amdgpu_device *adev);
@ -231,7 +234,7 @@ int psp_wait_for(struct psp_context *psp, uint32_t reg_index,
int i;
struct amdgpu_device *adev = psp->adev;
if (psp->adev->in_pci_err_recovery)
if (psp->adev->no_hw_access)
return 0;
for (i = 0; i < adev->usec_timeout; i++) {
@ -255,12 +258,15 @@ psp_cmd_submit_buf(struct psp_context *psp,
struct psp_gfx_cmd_resp *cmd, uint64_t fence_mc_addr)
{
int ret;
int index;
int index, idx;
int timeout = 20000;
bool ras_intr = false;
bool skip_unsupport = false;
if (psp->adev->in_pci_err_recovery)
if (psp->adev->no_hw_access)
return 0;
if (!drm_dev_enter(&psp->adev->ddev, &idx))
return 0;
mutex_lock(&psp->mutex);
@ -273,8 +279,7 @@ psp_cmd_submit_buf(struct psp_context *psp,
ret = psp_ring_cmd_submit(psp, psp->cmd_buf_mc_addr, fence_mc_addr, index);
if (ret) {
atomic_dec(&psp->fence_value);
mutex_unlock(&psp->mutex);
return ret;
goto exit;
}
amdgpu_asic_invalidate_hdp(psp->adev, NULL);
@ -314,8 +319,8 @@ psp_cmd_submit_buf(struct psp_context *psp,
psp->cmd_buf_mem->cmd_id,
psp->cmd_buf_mem->resp.status);
if (!timeout) {
mutex_unlock(&psp->mutex);
return -EINVAL;
ret = -EINVAL;
goto exit;
}
}
@ -323,8 +328,10 @@ psp_cmd_submit_buf(struct psp_context *psp,
ucode->tmr_mc_addr_lo = psp->cmd_buf_mem->resp.fw_addr_lo;
ucode->tmr_mc_addr_hi = psp->cmd_buf_mem->resp.fw_addr_hi;
}
mutex_unlock(&psp->mutex);
exit:
mutex_unlock(&psp->mutex);
drm_dev_exit(idx);
return ret;
}
@ -368,8 +375,7 @@ static int psp_load_toc(struct psp_context *psp,
if (!cmd)
return -ENOMEM;
/* Copy toc to psp firmware private buffer */
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
memcpy(psp->fw_pri_buf, psp->toc_start_addr, psp->toc_bin_size);
psp_copy_fw(psp, psp->toc_start_addr, psp->toc_bin_size);
psp_prep_load_toc_cmd_buf(cmd, psp->fw_pri_mc_addr, psp->toc_bin_size);
@ -604,8 +610,7 @@ static int psp_asd_load(struct psp_context *psp)
if (!cmd)
return -ENOMEM;
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
memcpy(psp->fw_pri_buf, psp->asd_start_addr, psp->asd_ucode_size);
psp_copy_fw(psp, psp->asd_start_addr, psp->asd_ucode_size);
psp_prep_asd_load_cmd_buf(cmd, psp->fw_pri_mc_addr,
psp->asd_ucode_size);
@ -760,8 +765,7 @@ static int psp_xgmi_load(struct psp_context *psp)
if (!cmd)
return -ENOMEM;
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
memcpy(psp->fw_pri_buf, psp->ta_xgmi_start_addr, psp->ta_xgmi_ucode_size);
psp_copy_fw(psp, psp->ta_xgmi_start_addr, psp->ta_xgmi_ucode_size);
psp_prep_ta_load_cmd_buf(cmd,
psp->fw_pri_mc_addr,
@ -1017,8 +1021,7 @@ static int psp_ras_load(struct psp_context *psp)
if (!cmd)
return -ENOMEM;
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
memcpy(psp->fw_pri_buf, psp->ta_ras_start_addr, psp->ta_ras_ucode_size);
psp_copy_fw(psp, psp->ta_ras_start_addr, psp->ta_ras_ucode_size);
ras_cmd = (struct ta_ras_shared_memory *)psp->ras.ras_shared_buf;
@ -1284,9 +1287,8 @@ static int psp_hdcp_load(struct psp_context *psp)
if (!cmd)
return -ENOMEM;
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
memcpy(psp->fw_pri_buf, psp->ta_hdcp_start_addr,
psp->ta_hdcp_ucode_size);
psp_copy_fw(psp, psp->ta_hdcp_start_addr,
psp->ta_hdcp_ucode_size);
psp_prep_ta_load_cmd_buf(cmd,
psp->fw_pri_mc_addr,
@ -1436,8 +1438,7 @@ static int psp_dtm_load(struct psp_context *psp)
if (!cmd)
return -ENOMEM;
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
memcpy(psp->fw_pri_buf, psp->ta_dtm_start_addr, psp->ta_dtm_ucode_size);
psp_copy_fw(psp, psp->ta_dtm_start_addr, psp->ta_dtm_ucode_size);
psp_prep_ta_load_cmd_buf(cmd,
psp->fw_pri_mc_addr,
@ -1582,8 +1583,7 @@ static int psp_rap_load(struct psp_context *psp)
if (!cmd)
return -ENOMEM;
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
memcpy(psp->fw_pri_buf, psp->ta_rap_start_addr, psp->ta_rap_ucode_size);
psp_copy_fw(psp, psp->ta_rap_start_addr, psp->ta_rap_ucode_size);
psp_prep_ta_load_cmd_buf(cmd,
psp->fw_pri_mc_addr,
@ -3020,7 +3020,7 @@ static ssize_t psp_usbc_pd_fw_sysfs_write(struct device *dev,
struct amdgpu_device *adev = drm_to_adev(ddev);
void *cpu_addr;
dma_addr_t dma_addr;
int ret;
int ret, idx;
char fw_name[100];
const struct firmware *usbc_pd_fw;
@ -3029,6 +3029,9 @@ static ssize_t psp_usbc_pd_fw_sysfs_write(struct device *dev,
return -EBUSY;
}
if (!drm_dev_enter(ddev, &idx))
return -ENODEV;
snprintf(fw_name, sizeof(fw_name), "amdgpu/%s", buf);
ret = request_firmware(&usbc_pd_fw, fw_name, adev->dev);
if (ret)
@ -3060,16 +3063,29 @@ static ssize_t psp_usbc_pd_fw_sysfs_write(struct device *dev,
rel_buf:
dma_free_coherent(adev->dev, usbc_pd_fw->size, cpu_addr, dma_addr);
release_firmware(usbc_pd_fw);
fail:
if (ret) {
DRM_ERROR("Failed to load USBC PD FW, err = %d", ret);
return ret;
count = ret;
}
drm_dev_exit(idx);
return count;
}
void psp_copy_fw(struct psp_context *psp, uint8_t *start_addr, uint32_t bin_size)
{
int idx;
if (!drm_dev_enter(&psp->adev->ddev, &idx))
return;
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
memcpy(psp->fw_pri_buf, start_addr, bin_size);
drm_dev_exit(idx);
}
static DEVICE_ATTR(usbc_pd_fw, S_IRUGO | S_IWUSR,
psp_usbc_pd_fw_sysfs_read,
psp_usbc_pd_fw_sysfs_write);

View File

@ -423,4 +423,6 @@ int psp_get_fw_attestation_records_addr(struct psp_context *psp,
int psp_load_fw_list(struct psp_context *psp,
struct amdgpu_firmware_info **ucode_list, int ucode_count);
void psp_copy_fw(struct psp_context *psp, uint8_t *start_addr, uint32_t bin_size);
#endif

View File

@ -2362,6 +2362,7 @@ int amdgpu_ras_pre_fini(struct amdgpu_device *adev)
if (!adev->ras_enabled || !con)
return 0;
/* Need disable ras on all IPs here before ip [hw/sw]fini */
amdgpu_ras_disable_all_features(adev, 0);
amdgpu_ras_recovery_fini(adev);

View File

@ -107,7 +107,8 @@ struct amdgpu_fence_driver {
};
int amdgpu_fence_driver_init(struct amdgpu_device *adev);
void amdgpu_fence_driver_fini(struct amdgpu_device *adev);
void amdgpu_fence_driver_fini_hw(struct amdgpu_device *adev);
void amdgpu_fence_driver_fini_sw(struct amdgpu_device *adev);
void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring);
int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring,

View File

@ -165,25 +165,6 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
*placement = abo->placement;
}
/**
* amdgpu_verify_access - Verify access for a mmap call
*
* @bo: The buffer object to map
* @filp: The file pointer from the process performing the mmap
*
* This is called by ttm_bo_mmap() to verify whether a process
* has the right to mmap a BO to their process space.
*/
static int amdgpu_verify_access(struct ttm_buffer_object *bo, struct file *filp)
{
struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo);
if (amdgpu_ttm_tt_get_usermm(bo->ttm))
return -EPERM;
return drm_vma_node_verify_access(&abo->tbo.base.vma_node,
filp->private_data);
}
/**
* amdgpu_ttm_map_buffer - Map memory into the GART windows
* @bo: buffer object to map
@ -1475,7 +1456,6 @@ static struct ttm_device_funcs amdgpu_bo_driver = {
.eviction_valuable = amdgpu_ttm_bo_eviction_valuable,
.evict_flags = &amdgpu_evict_flags,
.move = &amdgpu_bo_move,
.verify_access = &amdgpu_verify_access,
.delete_mem_notify = &amdgpu_bo_delete_mem_notify,
.release_notify = &amdgpu_bo_release_notify,
.io_mem_reserve = &amdgpu_ttm_io_mem_reserve,
@ -1785,10 +1765,6 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
amdgpu_bo_free_kernel(&adev->mman.discovery_memory, NULL, NULL);
amdgpu_ttm_fw_reserve_vram_fini(adev);
if (adev->mman.aper_base_kaddr)
iounmap(adev->mman.aper_base_kaddr);
adev->mman.aper_base_kaddr = NULL;
amdgpu_vram_mgr_fini(adev);
amdgpu_gtt_mgr_fini(adev);
ttm_range_man_fini(&adev->mman.bdev, AMDGPU_PL_GDS);
@ -1847,50 +1823,6 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
adev->mman.buffer_funcs_enabled = enable;
}
static vm_fault_t amdgpu_ttm_fault(struct vm_fault *vmf)
{
struct ttm_buffer_object *bo = vmf->vma->vm_private_data;
vm_fault_t ret;
ret = ttm_bo_vm_reserve(bo, vmf);
if (ret)
return ret;
ret = amdgpu_bo_fault_reserve_notify(bo);
if (ret)
goto unlock;
ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot,
TTM_BO_VM_NUM_PREFAULT, 1);
if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
return ret;
unlock:
dma_resv_unlock(bo->base.resv);
return ret;
}
static const struct vm_operations_struct amdgpu_ttm_vm_ops = {
.fault = amdgpu_ttm_fault,
.open = ttm_bo_vm_open,
.close = ttm_bo_vm_close,
.access = ttm_bo_vm_access
};
int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma)
{
struct drm_file *file_priv = filp->private_data;
struct amdgpu_device *adev = drm_to_adev(file_priv->minor->dev);
int r;
r = ttm_bo_mmap(filp, vma, &adev->mman.bdev);
if (unlikely(r != 0))
return r;
vma->vm_ops = &amdgpu_ttm_vm_ops;
return 0;
}
int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
uint64_t dst_offset, uint32_t byte_count,
struct dma_resv *resv,

View File

@ -142,7 +142,6 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
struct dma_resv *resv,
struct dma_fence **fence);
int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma);
int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo);
int amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo);
uint64_t amdgpu_ttm_domain_start(struct amdgpu_device *adev, uint32_t type);

View File

@ -32,6 +32,7 @@
#include <linux/module.h>
#include <drm/drm.h>
#include <drm/drm_drv.h>
#include "amdgpu.h"
#include "amdgpu_pm.h"
@ -375,7 +376,7 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev)
{
unsigned size;
void *ptr;
int i, j;
int i, j, idx;
bool in_ras_intr = amdgpu_ras_intr_triggered();
cancel_delayed_work_sync(&adev->uvd.idle_work);
@ -403,11 +404,15 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev)
if (!adev->uvd.inst[j].saved_bo)
return -ENOMEM;
/* re-write 0 since err_event_athub will corrupt VCPU buffer */
if (in_ras_intr)
memset(adev->uvd.inst[j].saved_bo, 0, size);
else
memcpy_fromio(adev->uvd.inst[j].saved_bo, ptr, size);
if (drm_dev_enter(&adev->ddev, &idx)) {
/* re-write 0 since err_event_athub will corrupt VCPU buffer */
if (in_ras_intr)
memset(adev->uvd.inst[j].saved_bo, 0, size);
else
memcpy_fromio(adev->uvd.inst[j].saved_bo, ptr, size);
drm_dev_exit(idx);
}
}
if (in_ras_intr)
@ -420,7 +425,7 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)
{
unsigned size;
void *ptr;
int i;
int i, idx;
for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
if (adev->uvd.harvest_config & (1 << i))
@ -432,7 +437,10 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)
ptr = adev->uvd.inst[i].cpu_addr;
if (adev->uvd.inst[i].saved_bo != NULL) {
memcpy_toio(ptr, adev->uvd.inst[i].saved_bo, size);
if (drm_dev_enter(&adev->ddev, &idx)) {
memcpy_toio(ptr, adev->uvd.inst[i].saved_bo, size);
drm_dev_exit(idx);
}
kvfree(adev->uvd.inst[i].saved_bo);
adev->uvd.inst[i].saved_bo = NULL;
} else {
@ -442,8 +450,11 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)
hdr = (const struct common_firmware_header *)adev->uvd.fw->data;
if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
memcpy_toio(adev->uvd.inst[i].cpu_addr, adev->uvd.fw->data + offset,
le32_to_cpu(hdr->ucode_size_bytes));
if (drm_dev_enter(&adev->ddev, &idx)) {
memcpy_toio(adev->uvd.inst[i].cpu_addr, adev->uvd.fw->data + offset,
le32_to_cpu(hdr->ucode_size_bytes));
drm_dev_exit(idx);
}
size -= le32_to_cpu(hdr->ucode_size_bytes);
ptr += le32_to_cpu(hdr->ucode_size_bytes);
}

View File

@ -29,6 +29,7 @@
#include <linux/module.h>
#include <drm/drm.h>
#include <drm/drm_drv.h>
#include "amdgpu.h"
#include "amdgpu_pm.h"
@ -293,7 +294,7 @@ int amdgpu_vce_resume(struct amdgpu_device *adev)
void *cpu_addr;
const struct common_firmware_header *hdr;
unsigned offset;
int r;
int r, idx;
if (adev->vce.vcpu_bo == NULL)
return -EINVAL;
@ -313,8 +314,12 @@ int amdgpu_vce_resume(struct amdgpu_device *adev)
hdr = (const struct common_firmware_header *)adev->vce.fw->data;
offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
memcpy_toio(cpu_addr, adev->vce.fw->data + offset,
adev->vce.fw->size - offset);
if (drm_dev_enter(&adev->ddev, &idx)) {
memcpy_toio(cpu_addr, adev->vce.fw->data + offset,
adev->vce.fw->size - offset);
drm_dev_exit(idx);
}
amdgpu_bo_kunmap(adev->vce.vcpu_bo);

View File

@ -27,6 +27,7 @@
#include <linux/firmware.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <drm/drm_drv.h>
#include "amdgpu.h"
#include "amdgpu_pm.h"
@ -283,7 +284,7 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev)
{
unsigned size;
void *ptr;
int i;
int i, idx;
cancel_delayed_work_sync(&adev->vcn.idle_work);
@ -300,7 +301,10 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev)
if (!adev->vcn.inst[i].saved_bo)
return -ENOMEM;
memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size);
if (drm_dev_enter(&adev->ddev, &idx)) {
memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size);
drm_dev_exit(idx);
}
}
return 0;
}
@ -309,7 +313,7 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev)
{
unsigned size;
void *ptr;
int i;
int i, idx;
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
if (adev->vcn.harvest_config & (1 << i))
@ -321,7 +325,10 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev)
ptr = adev->vcn.inst[i].cpu_addr;
if (adev->vcn.inst[i].saved_bo != NULL) {
memcpy_toio(ptr, adev->vcn.inst[i].saved_bo, size);
if (drm_dev_enter(&adev->ddev, &idx)) {
memcpy_toio(ptr, adev->vcn.inst[i].saved_bo, size);
drm_dev_exit(idx);
}
kvfree(adev->vcn.inst[i].saved_bo);
adev->vcn.inst[i].saved_bo = NULL;
} else {
@ -331,8 +338,11 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev)
hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
memcpy_toio(adev->vcn.inst[i].cpu_addr, adev->vcn.fw->data + offset,
le32_to_cpu(hdr->ucode_size_bytes));
if (drm_dev_enter(&adev->ddev, &idx)) {
memcpy_toio(adev->vcn.inst[i].cpu_addr, adev->vcn.fw->data + offset,
le32_to_cpu(hdr->ucode_size_bytes));
drm_dev_exit(idx);
}
size -= le32_to_cpu(hdr->ucode_size_bytes);
ptr += le32_to_cpu(hdr->ucode_size_bytes);
}

View File

@ -32,6 +32,7 @@
#include <linux/dma-buf.h>
#include <drm/amdgpu_drm.h>
#include <drm/drm_drv.h>
#include "amdgpu.h"
#include "amdgpu_trace.h"
#include "amdgpu_amdkfd.h"
@ -1633,7 +1634,10 @@ int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
struct amdgpu_vm_update_params params;
struct amdgpu_res_cursor cursor;
enum amdgpu_sync_mode sync_mode;
int r;
int r, idx;
if (!drm_dev_enter(&adev->ddev, &idx))
return -ENODEV;
memset(&params, 0, sizeof(params));
params.adev = adev;
@ -1728,6 +1732,7 @@ int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
error_unlock:
amdgpu_vm_eviction_unlock(vm);
drm_dev_exit(idx);
return r;
}

View File

@ -172,7 +172,7 @@ static DEVICE_ATTR(mem_info_vis_vram_used, S_IRUGO,
static DEVICE_ATTR(mem_info_vram_vendor, S_IRUGO,
amdgpu_mem_info_vram_vendor, NULL);
static const struct attribute *amdgpu_vram_mgr_attributes[] = {
static struct attribute *amdgpu_vram_mgr_attributes[] = {
&dev_attr_mem_info_vram_total.attr,
&dev_attr_mem_info_vis_vram_total.attr,
&dev_attr_mem_info_vram_used.attr,
@ -181,6 +181,10 @@ static const struct attribute *amdgpu_vram_mgr_attributes[] = {
NULL
};
const struct attribute_group amdgpu_vram_mgr_attr_group = {
.attrs = amdgpu_vram_mgr_attributes
};
/**
* amdgpu_vram_mgr_vis_size - Calculate visible node size
*
@ -684,7 +688,6 @@ int amdgpu_vram_mgr_init(struct amdgpu_device *adev)
{
struct amdgpu_vram_mgr *mgr = &adev->mman.vram_mgr;
struct ttm_resource_manager *man = &mgr->manager;
int ret;
ttm_resource_manager_init(man, adev->gmc.real_vram_size >> PAGE_SHIFT);
@ -695,11 +698,6 @@ int amdgpu_vram_mgr_init(struct amdgpu_device *adev)
INIT_LIST_HEAD(&mgr->reservations_pending);
INIT_LIST_HEAD(&mgr->reserved_pages);
/* Add the two VRAM-related sysfs files */
ret = sysfs_create_files(&adev->dev->kobj, amdgpu_vram_mgr_attributes);
if (ret)
DRM_ERROR("Failed to register sysfs\n");
ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_VRAM, &mgr->manager);
ttm_resource_manager_set_used(man, true);
return 0;
@ -737,8 +735,6 @@ void amdgpu_vram_mgr_fini(struct amdgpu_device *adev)
drm_mm_takedown(&mgr->mm);
spin_unlock(&mgr->lock);
sysfs_remove_files(&adev->dev->kobj, amdgpu_vram_mgr_attributes);
ttm_resource_manager_cleanup(man);
ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_VRAM, NULL);
}

View File

@ -309,8 +309,7 @@ static int cik_ih_sw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
amdgpu_irq_fini(adev);
amdgpu_ih_ring_fini(adev, &adev->irq.ih);
amdgpu_irq_fini_sw(adev);
amdgpu_irq_remove_domain(adev);
return 0;

View File

@ -301,8 +301,7 @@ static int cz_ih_sw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
amdgpu_irq_fini(adev);
amdgpu_ih_ring_fini(adev, &adev->irq.ih);
amdgpu_irq_fini_sw(adev);
amdgpu_irq_remove_domain(adev);
return 0;

View File

@ -7396,7 +7396,7 @@ static int gfx_v10_0_hw_fini(void *handle)
amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0);
amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0);
if (!adev->in_pci_err_recovery) {
if (!adev->no_hw_access) {
#ifndef BRING_UP_DEBUG
if (amdgpu_async_gfx_ring) {
r = gfx_v10_0_kiq_disable_kgq(adev);

View File

@ -956,7 +956,6 @@ static int gmc_v10_0_sw_init(void *handle)
static void gmc_v10_0_gart_fini(struct amdgpu_device *adev)
{
amdgpu_gart_table_vram_free(adev);
amdgpu_gart_fini(adev);
}
static int gmc_v10_0_sw_fini(void *handle)

View File

@ -898,7 +898,6 @@ static int gmc_v6_0_sw_fini(void *handle)
amdgpu_vm_manager_fini(adev);
amdgpu_gart_table_vram_free(adev);
amdgpu_bo_fini(adev);
amdgpu_gart_fini(adev);
release_firmware(adev->gmc.fw);
adev->gmc.fw = NULL;

View File

@ -1085,7 +1085,6 @@ static int gmc_v7_0_sw_fini(void *handle)
kfree(adev->gmc.vm_fault_info);
amdgpu_gart_table_vram_free(adev);
amdgpu_bo_fini(adev);
amdgpu_gart_fini(adev);
release_firmware(adev->gmc.fw);
adev->gmc.fw = NULL;

View File

@ -1201,7 +1201,6 @@ static int gmc_v8_0_sw_fini(void *handle)
kfree(adev->gmc.vm_fault_info);
amdgpu_gart_table_vram_free(adev);
amdgpu_bo_fini(adev);
amdgpu_gart_fini(adev);
release_firmware(adev->gmc.fw);
adev->gmc.fw = NULL;

View File

@ -1615,7 +1615,6 @@ static int gmc_v9_0_sw_fini(void *handle)
amdgpu_gart_table_vram_free(adev);
amdgpu_bo_unref(&adev->gmc.pdb0_bo);
amdgpu_bo_fini(adev);
amdgpu_gart_fini(adev);
return 0;
}

View File

@ -300,8 +300,7 @@ static int iceland_ih_sw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
amdgpu_irq_fini(adev);
amdgpu_ih_ring_fini(adev, &adev->irq.ih);
amdgpu_irq_fini_sw(adev);
amdgpu_irq_remove_domain(adev);
return 0;

View File

@ -586,11 +586,7 @@ static int navi10_ih_sw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
amdgpu_irq_fini(adev);
amdgpu_ih_ring_fini(adev, &adev->irq.ih_soft);
amdgpu_ih_ring_fini(adev, &adev->irq.ih2);
amdgpu_ih_ring_fini(adev, &adev->irq.ih1);
amdgpu_ih_ring_fini(adev, &adev->irq.ih);
amdgpu_irq_fini_sw(adev);
return 0;
}

View File

@ -23,6 +23,7 @@
#include <linux/firmware.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <drm/drm_drv.h>
#include "amdgpu.h"
#include "amdgpu_psp.h"
@ -282,10 +283,8 @@ static int psp_v11_0_bootloader_load_kdb(struct psp_context *psp)
if (ret)
return ret;
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
/* Copy PSP KDB binary to memory */
memcpy(psp->fw_pri_buf, psp->kdb_start_addr, psp->kdb_bin_size);
psp_copy_fw(psp, psp->kdb_start_addr, psp->kdb_bin_size);
/* Provide the PSP KDB to bootloader */
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36,
@ -315,10 +314,8 @@ static int psp_v11_0_bootloader_load_spl(struct psp_context *psp)
if (ret)
return ret;
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
/* Copy PSP SPL binary to memory */
memcpy(psp->fw_pri_buf, psp->spl_start_addr, psp->spl_bin_size);
psp_copy_fw(psp, psp->spl_start_addr, psp->spl_bin_size);
/* Provide the PSP SPL to bootloader */
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36,
@ -348,10 +345,8 @@ static int psp_v11_0_bootloader_load_sysdrv(struct psp_context *psp)
if (ret)
return ret;
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
/* Copy PSP System Driver binary to memory */
memcpy(psp->fw_pri_buf, psp->sys_start_addr, psp->sys_bin_size);
psp_copy_fw(psp, psp->sys_start_addr, psp->sys_bin_size);
/* Provide the sys driver to bootloader */
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36,
@ -384,10 +379,8 @@ static int psp_v11_0_bootloader_load_sos(struct psp_context *psp)
if (ret)
return ret;
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
/* Copy Secure OS binary to PSP memory */
memcpy(psp->fw_pri_buf, psp->sos_start_addr, psp->sos_bin_size);
psp_copy_fw(psp, psp->sos_start_addr, psp->sos_bin_size);
/* Provide the PSP secure OS to bootloader */
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36,
@ -621,7 +614,7 @@ static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops)
uint32_t p2c_header[4];
uint32_t sz;
void *buf;
int ret;
int ret, idx;
if (ctx->init == PSP_MEM_TRAIN_NOT_SUPPORT) {
DRM_DEBUG("Memory training is not supported.\n");
@ -694,17 +687,24 @@ static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops)
return -ENOMEM;
}
memcpy_fromio(buf, adev->mman.aper_base_kaddr, sz);
ret = psp_v11_0_memory_training_send_msg(psp, PSP_BL__DRAM_LONG_TRAIN);
if (ret) {
DRM_ERROR("Send long training msg failed.\n");
vfree(buf);
return ret;
}
if (drm_dev_enter(&adev->ddev, &idx)) {
memcpy_fromio(buf, adev->mman.aper_base_kaddr, sz);
ret = psp_v11_0_memory_training_send_msg(psp, PSP_BL__DRAM_LONG_TRAIN);
if (ret) {
DRM_ERROR("Send long training msg failed.\n");
vfree(buf);
drm_dev_exit(idx);
return ret;
}
memcpy_toio(adev->mman.aper_base_kaddr, buf, sz);
adev->hdp.funcs->flush_hdp(adev, NULL);
vfree(buf);
memcpy_toio(adev->mman.aper_base_kaddr, buf, sz);
adev->hdp.funcs->flush_hdp(adev, NULL);
vfree(buf);
drm_dev_exit(idx);
} else {
vfree(buf);
return -ENODEV;
}
}
if (ops & PSP_MEM_TRAIN_SAVE) {

View File

@ -138,10 +138,8 @@ static int psp_v12_0_bootloader_load_sysdrv(struct psp_context *psp)
if (ret)
return ret;
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
/* Copy PSP System Driver binary to memory */
memcpy(psp->fw_pri_buf, psp->sys_start_addr, psp->sys_bin_size);
psp_copy_fw(psp, psp->sys_start_addr, psp->sys_bin_size);
/* Provide the sys driver to bootloader */
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36,
@ -179,10 +177,8 @@ static int psp_v12_0_bootloader_load_sos(struct psp_context *psp)
if (ret)
return ret;
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
/* Copy Secure OS binary to PSP memory */
memcpy(psp->fw_pri_buf, psp->sos_start_addr, psp->sos_bin_size);
psp_copy_fw(psp, psp->sos_start_addr, psp->sos_bin_size);
/* Provide the PSP secure OS to bootloader */
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36,

View File

@ -102,10 +102,8 @@ static int psp_v3_1_bootloader_load_sysdrv(struct psp_context *psp)
if (ret)
return ret;
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
/* Copy PSP System Driver binary to memory */
memcpy(psp->fw_pri_buf, psp->sys_start_addr, psp->sys_bin_size);
psp_copy_fw(psp, psp->sys_start_addr, psp->sys_bin_size);
/* Provide the sys driver to bootloader */
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36,
@ -143,10 +141,8 @@ static int psp_v3_1_bootloader_load_sos(struct psp_context *psp)
if (ret)
return ret;
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
/* Copy Secure OS binary to PSP memory */
memcpy(psp->fw_pri_buf, psp->sos_start_addr, psp->sos_bin_size);
psp_copy_fw(psp, psp->sos_start_addr, psp->sos_bin_size);
/* Provide the PSP secure OS to bootloader */
WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36,

View File

@ -175,8 +175,7 @@ static int si_ih_sw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
amdgpu_irq_fini(adev);
amdgpu_ih_ring_fini(adev, &adev->irq.ih);
amdgpu_irq_fini_sw(adev);
return 0;
}

View File

@ -312,8 +312,7 @@ static int tonga_ih_sw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
amdgpu_irq_fini(adev);
amdgpu_ih_ring_fini(adev, &adev->irq.ih);
amdgpu_irq_fini_sw(adev);
amdgpu_irq_remove_domain(adev);
return 0;

View File

@ -25,6 +25,7 @@
*/
#include <linux/firmware.h>
#include <drm/drm_drv.h>
#include "amdgpu.h"
#include "amdgpu_vce.h"
@ -555,16 +556,19 @@ static int vce_v4_0_hw_fini(void *handle)
static int vce_v4_0_suspend(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int r;
int r, idx;
if (adev->vce.vcpu_bo == NULL)
return 0;
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
unsigned size = amdgpu_bo_size(adev->vce.vcpu_bo);
void *ptr = adev->vce.cpu_addr;
if (drm_dev_enter(&adev->ddev, &idx)) {
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
unsigned size = amdgpu_bo_size(adev->vce.vcpu_bo);
void *ptr = adev->vce.cpu_addr;
memcpy_fromio(adev->vce.saved_bo, ptr, size);
memcpy_fromio(adev->vce.saved_bo, ptr, size);
}
drm_dev_exit(idx);
}
r = vce_v4_0_hw_fini(adev);
@ -577,16 +581,20 @@ static int vce_v4_0_suspend(void *handle)
static int vce_v4_0_resume(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int r;
int r, idx;
if (adev->vce.vcpu_bo == NULL)
return -EINVAL;
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
unsigned size = amdgpu_bo_size(adev->vce.vcpu_bo);
void *ptr = adev->vce.cpu_addr;
memcpy_toio(ptr, adev->vce.saved_bo, size);
if (drm_dev_enter(&adev->ddev, &idx)) {
unsigned size = amdgpu_bo_size(adev->vce.vcpu_bo);
void *ptr = adev->vce.cpu_addr;
memcpy_toio(ptr, adev->vce.saved_bo, size);
drm_dev_exit(idx);
}
} else {
r = amdgpu_vce_resume(adev);
if (r)

View File

@ -34,6 +34,8 @@
#include "vcn/vcn_3_0_0_sh_mask.h"
#include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"
#include <drm/drm_drv.h>
#define mmUVD_CONTEXT_ID_INTERNAL_OFFSET 0x27
#define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET 0x0f
#define mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET 0x10
@ -276,16 +278,20 @@ static int vcn_v3_0_sw_init(void *handle)
static int vcn_v3_0_sw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int i, r;
int i, r, idx;
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
volatile struct amdgpu_fw_shared *fw_shared;
if (drm_dev_enter(&adev->ddev, &idx)) {
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
volatile struct amdgpu_fw_shared *fw_shared;
if (adev->vcn.harvest_config & (1 << i))
continue;
fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr;
fw_shared->present_flag_0 = 0;
fw_shared->sw_ring.is_enabled = false;
if (adev->vcn.harvest_config & (1 << i))
continue;
fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr;
fw_shared->present_flag_0 = 0;
fw_shared->sw_ring.is_enabled = false;
}
drm_dev_exit(idx);
}
if (amdgpu_sriov_vf(adev))

View File

@ -514,11 +514,7 @@ static int vega10_ih_sw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
amdgpu_irq_fini(adev);
amdgpu_ih_ring_fini(adev, &adev->irq.ih_soft);
amdgpu_ih_ring_fini(adev, &adev->irq.ih2);
amdgpu_ih_ring_fini(adev, &adev->irq.ih1);
amdgpu_ih_ring_fini(adev, &adev->irq.ih);
amdgpu_irq_fini_sw(adev);
return 0;
}

View File

@ -565,11 +565,7 @@ static int vega20_ih_sw_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
amdgpu_irq_fini(adev);
amdgpu_ih_ring_fini(adev, &adev->irq.ih_soft);
amdgpu_ih_ring_fini(adev, &adev->irq.ih2);
amdgpu_ih_ring_fini(adev, &adev->irq.ih1);
amdgpu_ih_ring_fini(adev, &adev->irq.ih);
amdgpu_irq_fini_sw(adev);
return 0;
}

View File

@ -891,7 +891,6 @@ out:
void kgd2kfd_device_exit(struct kfd_dev *kfd)
{
if (kfd->init_complete) {
kgd2kfd_suspend(kfd, false);
svm_migrate_fini((struct amdgpu_device *)kfd->kgd);
device_queue_manager_uninit(kfd->dqm);
kfd_interrupt_exit(kfd);

View File

@ -1291,6 +1291,15 @@ error:
return -EINVAL;
}
static int amdgpu_dm_early_fini(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
amdgpu_dm_audio_fini(adev);
return 0;
}
static void amdgpu_dm_fini(struct amdgpu_device *adev)
{
int i;
@ -1299,8 +1308,6 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
drm_encoder_cleanup(&adev->dm.mst_encoders[i].base);
}
amdgpu_dm_audio_fini(adev);
amdgpu_dm_destroy_drm_device(&adev->dm);
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
@ -2341,6 +2348,7 @@ static const struct amd_ip_funcs amdgpu_dm_funcs = {
.late_init = dm_late_init,
.sw_init = dm_sw_init,
.sw_fini = dm_sw_fini,
.early_fini = amdgpu_dm_early_fini,
.hw_init = dm_hw_init,
.hw_fini = dm_hw_fini,
.suspend = dm_suspend,
@ -3868,7 +3876,6 @@ fail:
static void amdgpu_dm_destroy_drm_device(struct amdgpu_display_manager *dm)
{
drm_mode_config_cleanup(dm->ddev);
drm_atomic_private_obj_fini(&dm->atomic_obj);
return;
}

View File

@ -461,8 +461,8 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
&aconnector->dm_dp_aux.aux,
16,
4,
(u8)max_link_enc_cap.lane_count,
(u8)max_link_enc_cap.link_rate,
max_link_enc_cap.lane_count,
drm_dp_bw_code_to_link_rate(max_link_enc_cap.link_rate),
aconnector->connector_id);
drm_connector_attach_dp_subconnector_property(&aconnector->base);

View File

@ -246,6 +246,7 @@ enum amd_dpm_forced_level;
* @late_init: sets up late driver/hw state (post hw_init) - Optional
* @sw_init: sets up driver state, does not configure hw
* @sw_fini: tears down driver state, does not configure hw
* @early_fini: tears down stuff before dev detached from driver
* @hw_init: sets up the hw state
* @hw_fini: tears down the hw state
* @late_fini: final cleanup
@ -274,6 +275,7 @@ struct amd_ip_funcs {
int (*late_init)(void *handle);
int (*sw_init)(void *handle);
int (*sw_fini)(void *handle);
int (*early_fini)(void *handle);
int (*hw_init)(void *handle);
int (*hw_fini)(void *handle);
void (*late_fini)(void *handle);

View File

@ -5178,11 +5178,11 @@ typedef struct _ATOM_LEAKAGE_VOLTAGE_OBJECT_V3
typedef struct _ATOM_SVID2_VOLTAGE_OBJECT_V3
{
ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader; // voltage mode = VOLTAGE_OBJ_SVID2
// 14:7 <EFBFBD> PSI0_VID
// 6 <EFBFBD> PSI0_EN
// 5 <EFBFBD> PSI1
// 4:2 <EFBFBD> load line slope trim.
// 1:0 <EFBFBD> offset trim,
// 14:7 - PSI0_VID
// 6 - PSI0_EN
// 5 - PSI1
// 4:2 - load line slope trim.
// 1:0 - offset trim,
USHORT usLoadLine_PSI;
// GPU GPIO pin Id to SVID2 regulator VRHot pin. possible value 0~31. 0 means GPIO0, 31 means GPIO31
UCHAR ucSVDGpioId; //0~31 indicate GPIO0~31

View File

@ -126,7 +126,7 @@ int smu_cmn_send_smc_msg_with_param(struct smu_context *smu,
struct amdgpu_device *adev = smu->adev;
int ret = 0, index = 0;
if (smu->adev->in_pci_err_recovery)
if (smu->adev->no_hw_access)
return 0;
index = smu_cmn_to_asic_specific_index(smu,

View File

@ -50,6 +50,19 @@ config DRM_CHRONTEL_CH7033
If in doubt, say "N".
config DRM_CROS_EC_ANX7688
tristate "ChromeOS EC ANX7688 bridge"
depends on OF
depends on I2C_CROS_EC_TUNNEL || COMPILE_TEST
select DRM_KMS_HELPER
select REGMAP_I2C
help
ChromeOS EC ANX7688 is an ultra-low power
4K Ultra-HD (4096x2160p60) mobile HD transmitter
designed for ChromeOS devices. It converts HDMI
2.0 to DisplayPort 1.3 Ultra-HD. It is connected
to the ChromeOS Embedded Controller.
config DRM_DISPLAY_CONNECTOR
tristate "Display connector support"
depends on OF

View File

@ -2,6 +2,7 @@
obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o
obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o
obj-$(CONFIG_DRM_DISPLAY_CONNECTOR) += display-connector.o
obj-$(CONFIG_DRM_LONTIUM_LT8912B) += lontium-lt8912b.o
obj-$(CONFIG_DRM_LONTIUM_LT9611) += lontium-lt9611.o

View File

@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/types.h>
@ -1005,33 +1006,6 @@ static void anx7625_power_on_init(struct anx7625_data *ctx)
}
}
static void anx7625_chip_control(struct anx7625_data *ctx, int state)
{
struct device *dev = &ctx->client->dev;
DRM_DEV_DEBUG_DRIVER(dev, "before set, power_state(%d).\n",
atomic_read(&ctx->power_status));
if (!ctx->pdata.low_power_mode)
return;
if (state) {
atomic_inc(&ctx->power_status);
if (atomic_read(&ctx->power_status) == 1)
anx7625_power_on_init(ctx);
} else {
if (atomic_read(&ctx->power_status)) {
atomic_dec(&ctx->power_status);
if (atomic_read(&ctx->power_status) == 0)
anx7625_power_standby(ctx);
}
}
DRM_DEV_DEBUG_DRIVER(dev, "after set, power_state(%d).\n",
atomic_read(&ctx->power_status));
}
static void anx7625_init_gpio(struct anx7625_data *platform)
{
struct device *dev = &platform->client->dev;
@ -1061,9 +1035,6 @@ static void anx7625_stop_dp_work(struct anx7625_data *ctx)
ctx->hpd_status = 0;
ctx->hpd_high_cnt = 0;
ctx->display_timing_valid = 0;
if (ctx->pdata.low_power_mode == 0)
anx7625_disable_pd_protocol(ctx);
}
static void anx7625_start_dp_work(struct anx7625_data *ctx)
@ -1105,49 +1076,26 @@ static void anx7625_hpd_polling(struct anx7625_data *ctx)
int ret, val;
struct device *dev = &ctx->client->dev;
if (atomic_read(&ctx->power_status) != 1) {
DRM_DEV_DEBUG_DRIVER(dev, "No need to poling HPD status.\n");
return;
}
ret = readx_poll_timeout(anx7625_read_hpd_status_p0,
ctx, val,
((val & HPD_STATUS) || (val < 0)),
5000,
5000 * 100);
if (ret) {
DRM_DEV_ERROR(dev, "HPD polling timeout!\n");
} else {
DRM_DEV_DEBUG_DRIVER(dev, "HPD raise up.\n");
anx7625_reg_write(ctx, ctx->i2c.tcpc_client,
INTR_ALERT_1, 0xFF);
anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
INTERFACE_CHANGE_INT, 0);
DRM_DEV_ERROR(dev, "no hpd.\n");
return;
}
DRM_DEV_DEBUG_DRIVER(dev, "system status: 0x%x. HPD raise up.\n", val);
anx7625_reg_write(ctx, ctx->i2c.tcpc_client,
INTR_ALERT_1, 0xFF);
anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
INTERFACE_CHANGE_INT, 0);
anx7625_start_dp_work(ctx);
}
static void anx7625_disconnect_check(struct anx7625_data *ctx)
{
if (atomic_read(&ctx->power_status) == 0)
anx7625_stop_dp_work(ctx);
}
static void anx7625_low_power_mode_check(struct anx7625_data *ctx,
int state)
{
struct device *dev = &ctx->client->dev;
DRM_DEV_DEBUG_DRIVER(dev, "low power mode check, state(%d).\n", state);
if (ctx->pdata.low_power_mode) {
anx7625_chip_control(ctx, state);
if (state)
anx7625_hpd_polling(ctx);
else
anx7625_disconnect_check(ctx);
}
if (!ctx->pdata.panel_bridge && ctx->bridge_attached)
drm_helper_hpd_irq_event(ctx->bridge.dev);
}
static void anx7625_remove_edid(struct anx7625_data *ctx)
@ -1180,9 +1128,6 @@ static int anx7625_hpd_change_detect(struct anx7625_data *ctx)
int intr_vector, status;
struct device *dev = &ctx->client->dev;
DRM_DEV_DEBUG_DRIVER(dev, "power_status=%d\n",
(u32)atomic_read(&ctx->power_status));
status = anx7625_reg_write(ctx, ctx->i2c.tcpc_client,
INTR_ALERT_1, 0xFF);
if (status < 0) {
@ -1228,22 +1173,25 @@ static void anx7625_work_func(struct work_struct *work)
struct anx7625_data, work);
mutex_lock(&ctx->lock);
if (pm_runtime_suspended(&ctx->client->dev))
goto unlock;
event = anx7625_hpd_change_detect(ctx);
mutex_unlock(&ctx->lock);
if (event < 0)
return;
goto unlock;
if (ctx->bridge_attached)
drm_helper_hpd_irq_event(ctx->bridge.dev);
unlock:
mutex_unlock(&ctx->lock);
}
static irqreturn_t anx7625_intr_hpd_isr(int irq, void *data)
{
struct anx7625_data *ctx = (struct anx7625_data *)data;
if (atomic_read(&ctx->power_status) != 1)
return IRQ_NONE;
queue_work(ctx->workqueue, &ctx->work);
return IRQ_HANDLED;
@ -1305,9 +1253,9 @@ static struct edid *anx7625_get_edid(struct anx7625_data *ctx)
return (struct edid *)edid;
}
anx7625_low_power_mode_check(ctx, 1);
pm_runtime_get_sync(dev);
edid_num = sp_tx_edid_read(ctx, p_edid->edid_raw_data);
anx7625_low_power_mode_check(ctx, 0);
pm_runtime_put_sync(dev);
if (edid_num < 1) {
DRM_DEV_ERROR(dev, "Fail to read EDID: %d\n", edid_num);
@ -1611,10 +1559,7 @@ static void anx7625_bridge_enable(struct drm_bridge *bridge)
DRM_DEV_DEBUG_DRIVER(dev, "drm enable\n");
anx7625_low_power_mode_check(ctx, 1);
if (WARN_ON(!atomic_read(&ctx->power_status)))
return;
pm_runtime_get_sync(dev);
anx7625_dp_start(ctx);
}
@ -1624,14 +1569,11 @@ static void anx7625_bridge_disable(struct drm_bridge *bridge)
struct anx7625_data *ctx = bridge_to_anx7625(bridge);
struct device *dev = &ctx->client->dev;
if (WARN_ON(!atomic_read(&ctx->power_status)))
return;
DRM_DEV_DEBUG_DRIVER(dev, "drm disable\n");
anx7625_dp_stop(ctx);
anx7625_low_power_mode_check(ctx, 0);
pm_runtime_put_sync(dev);
}
static enum drm_connector_status
@ -1735,6 +1677,71 @@ static void anx7625_unregister_i2c_dummy_clients(struct anx7625_data *ctx)
i2c_unregister_device(ctx->i2c.tcpc_client);
}
static int __maybe_unused anx7625_runtime_pm_suspend(struct device *dev)
{
struct anx7625_data *ctx = dev_get_drvdata(dev);
mutex_lock(&ctx->lock);
anx7625_stop_dp_work(ctx);
anx7625_power_standby(ctx);
mutex_unlock(&ctx->lock);
return 0;
}
static int __maybe_unused anx7625_runtime_pm_resume(struct device *dev)
{
struct anx7625_data *ctx = dev_get_drvdata(dev);
mutex_lock(&ctx->lock);
anx7625_power_on_init(ctx);
anx7625_hpd_polling(ctx);
mutex_unlock(&ctx->lock);
return 0;
}
static int __maybe_unused anx7625_resume(struct device *dev)
{
struct anx7625_data *ctx = dev_get_drvdata(dev);
if (!ctx->pdata.intp_irq)
return 0;
if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) {
enable_irq(ctx->pdata.intp_irq);
anx7625_runtime_pm_resume(dev);
}
return 0;
}
static int __maybe_unused anx7625_suspend(struct device *dev)
{
struct anx7625_data *ctx = dev_get_drvdata(dev);
if (!ctx->pdata.intp_irq)
return 0;
if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) {
anx7625_runtime_pm_suspend(dev);
disable_irq(ctx->pdata.intp_irq);
flush_workqueue(ctx->workqueue);
}
return 0;
}
static const struct dev_pm_ops anx7625_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(anx7625_suspend, anx7625_resume)
SET_RUNTIME_PM_OPS(anx7625_runtime_pm_suspend,
anx7625_runtime_pm_resume, NULL)
};
static int anx7625_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@ -1778,8 +1785,6 @@ static int anx7625_i2c_probe(struct i2c_client *client,
}
anx7625_init_gpio(platform);
atomic_set(&platform->power_status, 0);
mutex_init(&platform->lock);
platform->pdata.intp_irq = client->irq;
@ -1809,9 +1814,11 @@ static int anx7625_i2c_probe(struct i2c_client *client,
goto free_wq;
}
if (platform->pdata.low_power_mode == 0) {
pm_runtime_enable(dev);
if (!platform->pdata.low_power_mode) {
anx7625_disable_pd_protocol(platform);
atomic_set(&platform->power_status, 1);
pm_runtime_get_sync(dev);
}
/* Add work function */
@ -1847,6 +1854,9 @@ static int anx7625_i2c_remove(struct i2c_client *client)
if (platform->pdata.intp_irq)
destroy_workqueue(platform->workqueue);
if (!platform->pdata.low_power_mode)
pm_runtime_put_sync_suspend(&client->dev);
anx7625_unregister_i2c_dummy_clients(platform);
kfree(platform);
@ -1869,6 +1879,7 @@ static struct i2c_driver anx7625_driver = {
.driver = {
.name = "anx7625",
.of_match_table = anx_match_table,
.pm = &anx7625_pm_ops,
},
.probe = anx7625_i2c_probe,
.remove = anx7625_i2c_remove,

View File

@ -369,7 +369,6 @@ struct anx7625_i2c_client {
struct anx7625_data {
struct anx7625_platform_data pdata;
atomic_t power_status;
int hpd_status;
int hpd_high_cnt;
/* Lock for work queue */

View File

@ -2140,7 +2140,7 @@ cdns_mhdp_bridge_atomic_reset(struct drm_bridge *bridge)
if (!cdns_mhdp_state)
return NULL;
__drm_atomic_helper_bridge_reset(bridge, &cdns_mhdp_state->base);
__drm_atomic_helper_bridge_reset(bridge, &cdns_mhdp_state->base);
return &cdns_mhdp_state->base;
}
@ -2478,9 +2478,9 @@ static int cdns_mhdp_probe(struct platform_device *pdev)
clk_prepare_enable(clk);
pm_runtime_enable(dev);
ret = pm_runtime_get_sync(dev);
ret = pm_runtime_resume_and_get(dev);
if (ret < 0) {
dev_err(dev, "pm_runtime_get_sync failed\n");
dev_err(dev, "pm_runtime_resume_and_get failed\n");
pm_runtime_disable(dev);
goto clk_disable;
}

View File

@ -1028,7 +1028,7 @@ static ssize_t cdns_dsi_transfer(struct mipi_dsi_host *host,
struct mipi_dsi_packet packet;
int ret, i, tx_len, rx_len;
ret = pm_runtime_get_sync(host->dev);
ret = pm_runtime_resume_and_get(host->dev);
if (ret < 0)
return ret;

View File

@ -0,0 +1,191 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* CrOS EC ANX7688 HDMI->DP bridge driver
*
* Copyright 2020 Google LLC
*/
#include <drm/drm_bridge.h>
#include <drm/drm_print.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/types.h>
/* Register addresses */
#define ANX7688_VENDOR_ID_REG 0x00
#define ANX7688_DEVICE_ID_REG 0x02
#define ANX7688_FW_VERSION_REG 0x80
#define ANX7688_DP_BANDWIDTH_REG 0x85
#define ANX7688_DP_LANE_COUNT_REG 0x86
#define ANX7688_VENDOR_ID 0x1f29
#define ANX7688_DEVICE_ID 0x7688
/* First supported firmware version (0.85) */
#define ANX7688_MINIMUM_FW_VERSION 0x0085
static const struct regmap_config cros_ec_anx7688_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
struct cros_ec_anx7688 {
struct i2c_client *client;
struct regmap *regmap;
struct drm_bridge bridge;
bool filter;
};
static inline struct cros_ec_anx7688 *
bridge_to_cros_ec_anx7688(struct drm_bridge *bridge)
{
return container_of(bridge, struct cros_ec_anx7688, bridge);
}
static bool cros_ec_anx7688_bridge_mode_fixup(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
struct cros_ec_anx7688 *anx = bridge_to_cros_ec_anx7688(bridge);
int totalbw, requiredbw;
u8 dpbw, lanecount;
u8 regs[2];
int ret;
if (!anx->filter)
return true;
/* Read both regs 0x85 (bandwidth) and 0x86 (lane count). */
ret = regmap_bulk_read(anx->regmap, ANX7688_DP_BANDWIDTH_REG, regs, 2);
if (ret < 0) {
DRM_ERROR("Failed to read bandwidth/lane count\n");
return false;
}
dpbw = regs[0];
lanecount = regs[1];
/* Maximum 0x19 bandwidth (6.75 Gbps Turbo mode), 2 lanes */
if (dpbw > 0x19 || lanecount > 2) {
DRM_ERROR("Invalid bandwidth/lane count (%02x/%d)\n", dpbw,
lanecount);
return false;
}
/* Compute available bandwidth (kHz) */
totalbw = dpbw * lanecount * 270000 * 8 / 10;
/* Required bandwidth (8 bpc, kHz) */
requiredbw = mode->clock * 8 * 3;
DRM_DEBUG_KMS("DP bandwidth: %d kHz (%02x/%d); mode requires %d Khz\n",
totalbw, dpbw, lanecount, requiredbw);
if (totalbw == 0) {
DRM_ERROR("Bandwidth/lane count are 0, not rejecting modes\n");
return true;
}
return totalbw >= requiredbw;
}
static const struct drm_bridge_funcs cros_ec_anx7688_bridge_funcs = {
.mode_fixup = cros_ec_anx7688_bridge_mode_fixup,
};
static int cros_ec_anx7688_bridge_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct cros_ec_anx7688 *anx7688;
u16 vendor, device, fw_version;
u8 buffer[4];
int ret;
anx7688 = devm_kzalloc(dev, sizeof(*anx7688), GFP_KERNEL);
if (!anx7688)
return -ENOMEM;
anx7688->client = client;
i2c_set_clientdata(client, anx7688);
anx7688->regmap = devm_regmap_init_i2c(client, &cros_ec_anx7688_regmap_config);
if (IS_ERR(anx7688->regmap)) {
ret = PTR_ERR(anx7688->regmap);
dev_err(dev, "regmap i2c init failed: %d\n", ret);
return ret;
}
/* Read both vendor and device id (4 bytes). */
ret = regmap_bulk_read(anx7688->regmap, ANX7688_VENDOR_ID_REG,
buffer, 4);
if (ret) {
dev_err(dev, "Failed to read chip vendor/device id\n");
return ret;
}
vendor = (u16)buffer[1] << 8 | buffer[0];
device = (u16)buffer[3] << 8 | buffer[2];
if (vendor != ANX7688_VENDOR_ID || device != ANX7688_DEVICE_ID) {
dev_err(dev, "Invalid vendor/device id %04x/%04x\n",
vendor, device);
return -ENODEV;
}
ret = regmap_bulk_read(anx7688->regmap, ANX7688_FW_VERSION_REG,
buffer, 2);
if (ret) {
dev_err(dev, "Failed to read firmware version\n");
return ret;
}
fw_version = (u16)buffer[0] << 8 | buffer[1];
dev_info(dev, "ANX7688 firmware version 0x%04x\n", fw_version);
anx7688->bridge.of_node = dev->of_node;
/* FW version >= 0.85 supports bandwidth/lane count registers */
if (fw_version >= ANX7688_MINIMUM_FW_VERSION)
anx7688->filter = true;
else
/* Warn, but not fail, for backwards compatibility */
DRM_WARN("Old ANX7688 FW version (0x%04x), not filtering\n",
fw_version);
anx7688->bridge.funcs = &cros_ec_anx7688_bridge_funcs;
drm_bridge_add(&anx7688->bridge);
return 0;
}
static int cros_ec_anx7688_bridge_remove(struct i2c_client *client)
{
struct cros_ec_anx7688 *anx7688 = i2c_get_clientdata(client);
drm_bridge_remove(&anx7688->bridge);
return 0;
}
static const struct of_device_id cros_ec_anx7688_bridge_match_table[] = {
{ .compatible = "google,cros-ec-anx7688" },
{ }
};
MODULE_DEVICE_TABLE(of, cros_ec_anx7688_bridge_match_table);
static struct i2c_driver cros_ec_anx7688_bridge_driver = {
.probe_new = cros_ec_anx7688_bridge_probe,
.remove = cros_ec_anx7688_bridge_remove,
.driver = {
.name = "cros-ec-anx7688-bridge",
.of_match_table = cros_ec_anx7688_bridge_match_table,
},
};
module_i2c_driver(cros_ec_anx7688_bridge_driver);
MODULE_DESCRIPTION("ChromeOS EC ANX7688 HDMI->DP bridge driver");
MODULE_AUTHOR("Nicolas Boichat <drinkcat@chromium.org>");
MODULE_AUTHOR("Enric Balletbo i Serra <enric.balletbo@collabora.com>");
MODULE_LICENSE("GPL");

View File

@ -898,14 +898,14 @@ static int it66121_probe(struct i2c_client *client,
return -ENXIO;
}
ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0);
if (!ep)
return -EINVAL;
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0);
if (!ep)
return -EINVAL;
ctx->dev = dev;
ctx->client = client;
@ -943,7 +943,7 @@ static int it66121_probe(struct i2c_client *client,
ctx->regmap = devm_regmap_init_i2c(client, &it66121_regmap_config);
if (IS_ERR(ctx->regmap)) {
ite66121_power_off(ctx);
return PTR_ERR(ctx);
return PTR_ERR(ctx->regmap);
}
regmap_read(ctx->regmap, IT66121_VENDOR_ID0_REG, &vendor_ids[0]);

View File

@ -7,8 +7,6 @@
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/regmap.h>
#include <drm/drm_probe_helper.h>
@ -755,7 +753,6 @@ static struct i2c_driver lt8912_i2c_driver = {
.driver = {
.name = "lt8912",
.of_match_table = lt8912_dt_match,
.owner = THIS_MODULE,
},
.probe = lt8912_probe,
.remove = lt8912_remove,

View File

@ -1042,7 +1042,9 @@ exit:
pm_runtime_mark_last_busy(pdata->dev);
pm_runtime_put_autosuspend(pdata->dev);
return ret ? ret : len;
if (ret)
return ret;
return len;
}
static int ti_sn_bridge_parse_dsi_host(struct ti_sn65dsi86 *pdata)

View File

@ -685,6 +685,7 @@ static void drm_cleanup_buf_error(struct drm_device *dev,
dmah->size,
dmah->vaddr,
dmah->busaddr);
kfree(dmah);
}
}
kfree(entry->seglist);
@ -984,8 +985,16 @@ int drm_legacy_addbufs_pci(struct drm_device *dev,
while (entry->buf_count < count) {
dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL);
if (!dmah)
if (!dmah) {
/* Set count correctly so we free the proper amount. */
entry->buf_count = count;
entry->seg_count = count;
drm_cleanup_buf_error(dev, entry);
kfree(temp_pagelist);
mutex_unlock(&dev->struct_mutex);
atomic_dec(&dev->buf_alloc);
return -ENOMEM;
}
dmah->size = total;
dmah->vaddr = dma_alloc_coherent(dev->dev,

View File

@ -3722,9 +3722,9 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms
}
lane_count = min_t(int, mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK, mgr->max_lane_count);
link_rate = min_t(int, mgr->dpcd[1], mgr->max_link_rate);
link_rate = min_t(int, drm_dp_bw_code_to_link_rate(mgr->dpcd[1]), mgr->max_link_rate);
mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr,
drm_dp_bw_code_to_link_rate(link_rate),
link_rate,
lane_count);
if (mgr->pbn_div == 0) {
ret = -EINVAL;
@ -5454,7 +5454,7 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
* @max_dpcd_transaction_bytes: hw specific DPCD transaction limit
* @max_payloads: maximum number of payloads this GPU can source
* @max_lane_count: maximum number of lanes this GPU supports
* @max_link_rate: maximum link rate this GPU supports, units as in DPCD
* @max_link_rate: maximum link rate per lane this GPU supports in kHz
* @conn_base_id: the connector object ID the MST device is connected to.
*
* Return 0 for success, or negative error code on failure
@ -5462,7 +5462,7 @@ EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
struct drm_device *dev, struct drm_dp_aux *aux,
int max_dpcd_transaction_bytes, int max_payloads,
u8 max_lane_count, u8 max_link_rate,
int max_lane_count, int max_link_rate,
int conn_base_id)
{
struct drm_dp_mst_topology_state *mst_state;

View File

@ -9,12 +9,14 @@
* Copyright (C) 2012 Red Hat
*/
#include <drm/drm_damage_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_plane.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
/**
@ -97,3 +99,47 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb,
return paddr;
}
EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_addr);
/**
* drm_fb_cma_sync_non_coherent - Sync GEM object to non-coherent backing
* memory
* @drm: DRM device
* @old_state: Old plane state
* @state: New plane state
*
* This function can be used by drivers that use damage clips and have
* CMA GEM objects backed by non-coherent memory. Calling this function
* in a plane's .atomic_update ensures that all the data in the backing
* memory have been written to RAM.
*/
void drm_fb_cma_sync_non_coherent(struct drm_device *drm,
struct drm_plane_state *old_state,
struct drm_plane_state *state)
{
const struct drm_format_info *finfo = state->fb->format;
struct drm_atomic_helper_damage_iter iter;
const struct drm_gem_cma_object *cma_obj;
unsigned int offset, i;
struct drm_rect clip;
dma_addr_t daddr;
size_t nb_bytes;
for (i = 0; i < finfo->num_planes; i++) {
cma_obj = drm_fb_cma_get_gem_obj(state->fb, i);
if (!cma_obj->map_noncoherent)
continue;
daddr = drm_fb_cma_get_gem_addr(state->fb, state, i);
drm_atomic_helper_damage_iter_init(&iter, old_state, state);
drm_atomic_for_each_plane_damage(&iter, &clip) {
/* Ignore x1/x2 values, invalidate complete lines */
offset = clip.y1 * state->fb->pitches[i];
nb_bytes = (clip.y2 - clip.y1) * state->fb->pitches[i];
dma_sync_single_for_device(drm->dev, daddr + offset,
nb_bytes, DMA_TO_DEVICE);
}
}
}
EXPORT_SYMBOL_GPL(drm_fb_cma_sync_non_coherent);

View File

@ -1737,7 +1737,7 @@ void drm_fb_helper_fill_info(struct fb_info *info,
sizes->fb_width, sizes->fb_height);
info->par = fb_helper;
snprintf(info->fix.id, sizeof(info->fix.id), "%sdrmfb",
snprintf(info->fix.id, sizeof(info->fix.id), "%s",
fb_helper->dev->driver->name);
}

View File

@ -30,11 +30,6 @@
#include <drm/drm_device.h>
#include <drm/drm_fourcc.h>
static char printable_char(int c)
{
return isascii(c) && isprint(c) ? c : '?';
}
/**
* drm_mode_legacy_fb_format - compute drm fourcc code from legacy description
* @bpp: bits per pixels
@ -130,26 +125,6 @@ uint32_t drm_driver_legacy_fb_format(struct drm_device *dev,
}
EXPORT_SYMBOL(drm_driver_legacy_fb_format);
/**
* drm_get_format_name - fill a string with a drm fourcc format's name
* @format: format to compute name of
* @buf: caller-supplied buffer
*/
const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf *buf)
{
snprintf(buf->str, sizeof(buf->str),
"%c%c%c%c %s-endian (0x%08x)",
printable_char(format & 0xff),
printable_char((format >> 8) & 0xff),
printable_char((format >> 16) & 0xff),
printable_char((format >> 24) & 0x7f),
format & DRM_FORMAT_BIG_ENDIAN ? "big" : "little",
format);
return buf->str;
}
EXPORT_SYMBOL(drm_get_format_name);
/*
* Internal function to query information for a given format. See
* drm_format_info() for the public API.

View File

@ -46,6 +46,7 @@ static const struct drm_gem_object_funcs drm_gem_cma_default_funcs = {
* __drm_gem_cma_create - Create a GEM CMA object without allocating memory
* @drm: DRM device
* @size: size of the object to allocate
* @private: true if used for internal purposes
*
* This function creates and initializes a GEM CMA object of the given size,
* but doesn't allocate any memory to back the object.
@ -55,11 +56,11 @@ static const struct drm_gem_object_funcs drm_gem_cma_default_funcs = {
* error code on failure.
*/
static struct drm_gem_cma_object *
__drm_gem_cma_create(struct drm_device *drm, size_t size)
__drm_gem_cma_create(struct drm_device *drm, size_t size, bool private)
{
struct drm_gem_cma_object *cma_obj;
struct drm_gem_object *gem_obj;
int ret;
int ret = 0;
if (drm->driver->gem_create_object)
gem_obj = drm->driver->gem_create_object(drm, size);
@ -73,7 +74,14 @@ __drm_gem_cma_create(struct drm_device *drm, size_t size)
cma_obj = container_of(gem_obj, struct drm_gem_cma_object, base);
ret = drm_gem_object_init(drm, gem_obj, size);
if (private) {
drm_gem_private_object_init(drm, gem_obj, size);
/* Always use writecombine for dma-buf mappings */
cma_obj->map_noncoherent = false;
} else {
ret = drm_gem_object_init(drm, gem_obj, size);
}
if (ret)
goto error;
@ -111,12 +119,19 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
size = round_up(size, PAGE_SIZE);
cma_obj = __drm_gem_cma_create(drm, size);
cma_obj = __drm_gem_cma_create(drm, size, false);
if (IS_ERR(cma_obj))
return cma_obj;
cma_obj->vaddr = dma_alloc_wc(drm->dev, size, &cma_obj->paddr,
GFP_KERNEL | __GFP_NOWARN);
if (cma_obj->map_noncoherent) {
cma_obj->vaddr = dma_alloc_noncoherent(drm->dev, size,
&cma_obj->paddr,
DMA_TO_DEVICE,
GFP_KERNEL | __GFP_NOWARN);
} else {
cma_obj->vaddr = dma_alloc_wc(drm->dev, size, &cma_obj->paddr,
GFP_KERNEL | __GFP_NOWARN);
}
if (!cma_obj->vaddr) {
drm_dbg(drm, "failed to allocate buffer with size %zu\n",
size);
@ -432,7 +447,7 @@ drm_gem_cma_prime_import_sg_table(struct drm_device *dev,
return ERR_PTR(-EINVAL);
/* Create a CMA GEM buffer. */
cma_obj = __drm_gem_cma_create(dev, attach->dmabuf->size);
cma_obj = __drm_gem_cma_create(dev, attach->dmabuf->size, true);
if (IS_ERR(cma_obj))
return ERR_CAST(cma_obj);
@ -499,8 +514,16 @@ int drm_gem_cma_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
cma_obj = to_drm_gem_cma_obj(obj);
ret = dma_mmap_wc(cma_obj->base.dev->dev, vma, cma_obj->vaddr,
cma_obj->paddr, vma->vm_end - vma->vm_start);
if (cma_obj->map_noncoherent) {
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
ret = dma_mmap_pages(cma_obj->base.dev->dev,
vma, vma->vm_end - vma->vm_start,
virt_to_page(cma_obj->vaddr));
} else {
ret = dma_mmap_wc(cma_obj->base.dev->dev, vma, cma_obj->vaddr,
cma_obj->paddr, vma->vm_end - vma->vm_start);
}
if (ret)
drm_gem_vm_close(vma);

View File

@ -149,8 +149,10 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev,
int ret, i;
info = drm_get_format_info(dev, mode_cmd);
if (!info)
if (!info) {
drm_dbg_kms(dev, "Failed to get FB format info\n");
return -EINVAL;
}
for (i = 0; i < info->num_planes; i++) {
unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
@ -169,6 +171,9 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev,
+ mode_cmd->offsets[i];
if (objs[i]->size < min_size) {
drm_dbg_kms(dev,
"GEM object size (%zu) smaller than minimum size (%u) for plane %d\n",
objs[i]->size, min_size, i);
drm_gem_object_put(objs[i]);
ret = -EINVAL;
goto err_gem_object_put;

View File

@ -54,18 +54,10 @@ void drm_lastclose(struct drm_device *dev);
#ifdef CONFIG_PCI
/* drm_pci.c */
int drm_legacy_irq_by_busid(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master);
#else
static inline int drm_legacy_irq_by_busid(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
return -EINVAL;
}
static inline int drm_pci_set_busid(struct drm_device *dev,
struct drm_master *master)
{

View File

@ -577,7 +577,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_legacy_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_legacy_irq_by_busid,
DRM_MASTER|DRM_ROOT_ONLY),
DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_legacy_getmap_ioctl, 0),

View File

@ -14,7 +14,6 @@
#include "drm_crtc_internal.h"
#include "drm_internal.h"
#include "drm_legacy.h"
#define drm_for_each_lessee(lessee, lessor) \
list_for_each_entry((lessee), &(lessor)->lessees, lessee_list)

View File

@ -235,9 +235,17 @@ void drm_master_legacy_init(struct drm_master *master);
static inline void drm_master_legacy_init(struct drm_master *master) {}
#endif
/* drm_pci.c */
#if IS_ENABLED(CONFIG_DRM_LEGACY) && IS_ENABLED(CONFIG_PCI)
int drm_legacy_irq_by_busid(struct drm_device *dev, void *data, struct drm_file *file_priv);
void drm_legacy_pci_agp_destroy(struct drm_device *dev);
#else
static inline int drm_legacy_irq_by_busid(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
return -EINVAL;
}
static inline void drm_legacy_pci_agp_destroy(struct drm_device *dev) {}
#endif

View File

@ -72,7 +72,9 @@ int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master)
return 0;
}
static int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p)
#ifdef CONFIG_DRM_LEGACY
static int drm_legacy_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p)
{
struct pci_dev *pdev = to_pci_dev(dev->dev);
@ -115,11 +117,9 @@ int drm_legacy_irq_by_busid(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return -EOPNOTSUPP;
return drm_pci_irq_by_busid(dev, p);
return drm_legacy_pci_irq_by_busid(dev, p);
}
#ifdef CONFIG_DRM_LEGACY
void drm_legacy_pci_agp_destroy(struct drm_device *dev)
{
if (dev->agp) {
@ -165,9 +165,6 @@ static int drm_legacy_get_pci_dev(struct pci_dev *pdev,
dev->hose = pdev->sysdata;
#endif
if (drm_core_check_feature(dev, DRIVER_MODESET))
pci_set_drvdata(pdev, dev);
drm_legacy_pci_agp_init(dev);
ret = drm_dev_register(dev, ent->driver_data);

View File

@ -3,7 +3,7 @@
* DesignWare MIPI DSI Host Controller v1.02 driver
*
* Copyright (c) 2016 Linaro Limited.
* Copyright (c) 2014-2016 Hisilicon Limited.
* Copyright (c) 2014-2016 HiSilicon Limited.
*
* Author:
* Xinliang Liu <z.liuxinliang@hisilicon.com>

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016 Linaro Limited.
* Copyright (c) 2014-2016 Hisilicon Limited.
* Copyright (c) 2014-2016 HiSilicon Limited.
*/
#ifndef __DW_DSI_REG_H__

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016 Linaro Limited.
* Copyright (c) 2014-2016 Hisilicon Limited.
* Copyright (c) 2014-2016 HiSilicon Limited.
*/
#ifndef __KIRIN_ADE_REG_H__

View File

@ -3,7 +3,7 @@
* Hisilicon Hi6220 SoC ADE(Advanced Display Engine)'s crtc&plane driver
*
* Copyright (c) 2016 Linaro Limited.
* Copyright (c) 2014-2016 Hisilicon Limited.
* Copyright (c) 2014-2016 HiSilicon Limited.
*
* Author:
* Xinliang Liu <z.liuxinliang@hisilicon.com>

View File

@ -3,7 +3,7 @@
* Hisilicon Kirin SoCs drm master driver
*
* Copyright (c) 2016 Linaro Limited.
* Copyright (c) 2014-2016 Hisilicon Limited.
* Copyright (c) 2014-2016 HiSilicon Limited.
*
* Author:
* Xinliang Liu <z.liuxinliang@hisilicon.com>

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016 Linaro Limited.
* Copyright (c) 2014-2016 Hisilicon Limited.
* Copyright (c) 2014-2016 HiSilicon Limited.
*/
#ifndef __KIRIN_DRM_DRV_H__

View File

@ -963,8 +963,8 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id)
intel_dp_create_fake_mst_encoders(dig_port);
ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
&intel_dp->aux, 16, 3,
(u8)dig_port->max_lanes,
drm_dp_link_rate_to_bw_code(max_source_rate),
dig_port->max_lanes,
max_source_rate,
conn_base_id);
if (ret)
return ret;

View File

@ -8,7 +8,6 @@
#include <linux/shmem_fs.h>
#include <linux/swap.h>
#include <drm/drm.h> /* for drm_legacy.h! */
#include <drm/drm_cache.h>
#include "gt/intel_gt.h"

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: MIT*/
/*
* Copyright <EFBFBD> 2003-2018 Intel Corporation
* Copyright © 2003-2018 Intel Corporation
*/
#ifndef _INTEL_GPU_COMMANDS_H_

View File

@ -51,7 +51,6 @@
#include <linux/xarray.h>
#include <drm/intel-gtt.h>
#include <drm/drm_legacy.h> /* for struct drm_dma_handle */
#include <drm/drm_gem.h>
#include <drm/drm_auth.h>
#include <drm/drm_cache.h>

View File

@ -1,7 +1,7 @@
/*
* SPDX-License-Identifier: MIT
*
* Copyright <EFBFBD> 2008-2018 Intel Corporation
* Copyright © 2008-2018 Intel Corporation
*/
#ifndef _I915_GPU_ERROR_H_

View File

@ -9,6 +9,7 @@
#include <linux/component.h>
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of_device.h>
@ -23,6 +24,7 @@
#include <drm/drm_color_mgmt.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_encoder.h>
#include <drm/drm_gem_cma_helper.h>
@ -57,6 +59,7 @@ struct ingenic_dma_hwdescs {
struct jz_soc_info {
bool needs_dev_clk;
bool has_osd;
bool map_noncoherent;
unsigned int max_width, max_height;
const u32 *formats_f0, *formats_f1;
unsigned int num_formats_f0, num_formats_f1;
@ -342,7 +345,7 @@ static void ingenic_drm_crtc_atomic_flush(struct drm_crtc *crtc,
if (priv->update_clk_rate) {
mutex_lock(&priv->clk_mutex);
clk_set_rate(priv->pix_clk,
crtc_state->adjusted_mode.clock * 1000);
crtc_state->adjusted_mode.crtc_clock * 1000);
priv->update_clk_rate = false;
mutex_unlock(&priv->clk_mutex);
}
@ -410,6 +413,9 @@ static int ingenic_drm_plane_atomic_check(struct drm_plane *plane,
old_plane_state->fb->format->format != new_plane_state->fb->format->format))
crtc_state->mode_changed = true;
if (priv->soc_info->map_noncoherent)
drm_atomic_helper_check_plane_damage(state, new_plane_state);
return 0;
}
@ -526,6 +532,13 @@ void ingenic_drm_plane_config(struct device *dev,
}
}
bool ingenic_drm_map_noncoherent(const struct device *dev)
{
const struct ingenic_drm *priv = dev_get_drvdata(dev);
return priv->soc_info->map_noncoherent;
}
static void ingenic_drm_update_palette(struct ingenic_drm *priv,
const struct drm_color_lut *lut)
{
@ -544,8 +557,8 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane,
struct drm_atomic_state *state)
{
struct ingenic_drm *priv = drm_device_get_priv(plane->dev);
struct drm_plane_state *newstate = drm_atomic_get_new_plane_state(state,
plane);
struct drm_plane_state *newstate = drm_atomic_get_new_plane_state(state, plane);
struct drm_plane_state *oldstate = drm_atomic_get_old_plane_state(state, plane);
struct drm_crtc_state *crtc_state;
struct ingenic_dma_hwdesc *hwdesc;
unsigned int width, height, cpp, offset;
@ -553,6 +566,9 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane,
u32 fourcc;
if (newstate && newstate->fb) {
if (priv->soc_info->map_noncoherent)
drm_fb_cma_sync_non_coherent(&priv->drm, oldstate, newstate);
crtc_state = newstate->crtc->state;
addr = drm_fb_cma_get_gem_addr(newstate->fb, newstate, 0);
@ -742,6 +758,33 @@ static void ingenic_drm_disable_vblank(struct drm_crtc *crtc)
regmap_update_bits(priv->map, JZ_REG_LCD_CTRL, JZ_LCD_CTRL_EOF_IRQ, 0);
}
static struct drm_framebuffer *
ingenic_drm_gem_fb_create(struct drm_device *drm, struct drm_file *file,
const struct drm_mode_fb_cmd2 *mode_cmd)
{
struct ingenic_drm *priv = drm_device_get_priv(drm);
if (priv->soc_info->map_noncoherent)
return drm_gem_fb_create_with_dirty(drm, file, mode_cmd);
return drm_gem_fb_create(drm, file, mode_cmd);
}
static struct drm_gem_object *
ingenic_drm_gem_create_object(struct drm_device *drm, size_t size)
{
struct ingenic_drm *priv = drm_device_get_priv(drm);
struct drm_gem_cma_object *obj;
obj = kzalloc(sizeof(*obj), GFP_KERNEL);
if (!obj)
return ERR_PTR(-ENOMEM);
obj->map_noncoherent = priv->soc_info->map_noncoherent;
return &obj->base;
}
DEFINE_DRM_GEM_CMA_FOPS(ingenic_drm_fops);
static const struct drm_driver ingenic_drm_driver_data = {
@ -754,6 +797,7 @@ static const struct drm_driver ingenic_drm_driver_data = {
.patchlevel = 0,
.fops = &ingenic_drm_fops,
.gem_create_object = ingenic_drm_gem_create_object,
DRM_GEM_CMA_DRIVER_OPS,
.irq_handler = ingenic_drm_irq_handler,
@ -804,7 +848,7 @@ static const struct drm_encoder_helper_funcs ingenic_drm_encoder_helper_funcs =
};
static const struct drm_mode_config_funcs ingenic_drm_mode_config_funcs = {
.fb_create = drm_gem_fb_create,
.fb_create = ingenic_drm_gem_fb_create,
.output_poll_changed = drm_fb_helper_output_poll_changed,
.atomic_check = drm_atomic_helper_check,
.atomic_commit = drm_atomic_helper_commit,
@ -961,6 +1005,9 @@ static int ingenic_drm_bind(struct device *dev, bool has_components)
return ret;
}
if (soc_info->map_noncoherent)
drm_plane_enable_fb_damage_clips(&priv->f1);
drm_crtc_helper_add(&priv->crtc, &ingenic_drm_crtc_helper_funcs);
ret = drm_crtc_init_with_planes(drm, &priv->crtc, primary,
@ -989,6 +1036,9 @@ static int ingenic_drm_bind(struct device *dev, bool has_components)
return ret;
}
if (soc_info->map_noncoherent)
drm_plane_enable_fb_damage_clips(&priv->f0);
if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU) && has_components) {
ret = component_bind_all(dev, drm);
if (ret) {
@ -1245,6 +1295,7 @@ static const u32 jz4770_formats_f0[] = {
static const struct jz_soc_info jz4740_soc_info = {
.needs_dev_clk = true,
.has_osd = false,
.map_noncoherent = false,
.max_width = 800,
.max_height = 600,
.formats_f1 = jz4740_formats,
@ -1255,6 +1306,7 @@ static const struct jz_soc_info jz4740_soc_info = {
static const struct jz_soc_info jz4725b_soc_info = {
.needs_dev_clk = false,
.has_osd = true,
.map_noncoherent = false,
.max_width = 800,
.max_height = 600,
.formats_f1 = jz4725b_formats_f1,
@ -1266,6 +1318,7 @@ static const struct jz_soc_info jz4725b_soc_info = {
static const struct jz_soc_info jz4770_soc_info = {
.needs_dev_clk = false,
.has_osd = true,
.map_noncoherent = true,
.max_width = 1280,
.max_height = 720,
.formats_f1 = jz4770_formats_f1,

View File

@ -184,6 +184,7 @@ struct platform_driver;
void ingenic_drm_plane_config(struct device *dev,
struct drm_plane *plane, u32 fourcc);
void ingenic_drm_plane_disable(struct device *dev, struct drm_plane *plane);
bool ingenic_drm_map_noncoherent(const struct device *dev);
extern struct platform_driver *ingenic_ipu_driver_ptr;

View File

@ -20,10 +20,13 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_plane.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_property.h>
@ -285,8 +288,8 @@ static void ingenic_ipu_plane_atomic_update(struct drm_plane *plane,
struct drm_atomic_state *state)
{
struct ingenic_ipu *ipu = plane_to_ingenic_ipu(plane);
struct drm_plane_state *newstate = drm_atomic_get_new_plane_state(state,
plane);
struct drm_plane_state *newstate = drm_atomic_get_new_plane_state(state, plane);
struct drm_plane_state *oldstate = drm_atomic_get_old_plane_state(state, plane);
const struct drm_format_info *finfo;
u32 ctrl, stride = 0, coef_index = 0, format = 0;
bool needs_modeset, upscaling_w, upscaling_h;
@ -317,6 +320,9 @@ static void ingenic_ipu_plane_atomic_update(struct drm_plane *plane,
JZ_IPU_CTRL_CHIP_EN | JZ_IPU_CTRL_LCDC_SEL);
}
if (ingenic_drm_map_noncoherent(ipu->master))
drm_fb_cma_sync_non_coherent(ipu->drm, oldstate, newstate);
/* New addresses will be committed in vblank handler... */
ipu->addr_y = drm_fb_cma_get_gem_addr(newstate->fb, newstate, 0);
if (finfo->num_planes > 1)
@ -541,7 +547,7 @@ static int ingenic_ipu_plane_atomic_check(struct drm_plane *plane,
if (!new_plane_state->crtc ||
!crtc_state->mode.hdisplay || !crtc_state->mode.vdisplay)
return 0;
goto out_check_damage;
/* Plane must be fully visible */
if (new_plane_state->crtc_x < 0 || new_plane_state->crtc_y < 0 ||
@ -558,7 +564,7 @@ static int ingenic_ipu_plane_atomic_check(struct drm_plane *plane,
return -EINVAL;
if (!osd_changed(new_plane_state, old_plane_state))
return 0;
goto out_check_damage;
crtc_state->mode_changed = true;
@ -592,6 +598,10 @@ static int ingenic_ipu_plane_atomic_check(struct drm_plane *plane,
ipu->denom_w = denom_w;
ipu->denom_h = denom_h;
out_check_damage:
if (ingenic_drm_map_noncoherent(ipu->master))
drm_atomic_helper_check_plane_damage(state, new_plane_state);
return 0;
}
@ -773,6 +783,9 @@ static int ingenic_ipu_bind(struct device *dev, struct device *master, void *d)
return err;
}
if (ingenic_drm_map_noncoherent(master))
drm_plane_enable_fb_damage_clips(plane);
/*
* Sharpness settings range is [0,32]
* 0 : nearest-neighbor

View File

@ -1196,10 +1196,8 @@ static int mcde_dsi_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
d->regs = devm_ioremap_resource(dev, res);
if (IS_ERR(d->regs)) {
dev_err(dev, "no DSI regs\n");
if (IS_ERR(d->regs))
return PTR_ERR(d->regs);
}
dsi_id = readl(d->regs + DSI_ID_REG);
dev_info(dev, "HW revision 0x%08x\n", dsi_id);

View File

@ -1617,8 +1617,9 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max,
mstm->mgr.cbs = &nv50_mstm;
ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev, aux, aux_max,
(u8)max_payloads, outp->dcb->dpconf.link_nr,
(u8)outp->dcb->dpconf.link_bw, conn_base_id);
max_payloads, outp->dcb->dpconf.link_nr,
drm_dp_bw_code_to_link_rate(outp->dcb->dpconf.link_bw),
conn_base_id);
if (ret)
return ret;

Some files were not shown because too many files have changed in this diff Show More