diff --git a/Documentation/devicetree/bindings/display/panel/edt,et-series.txt b/Documentation/devicetree/bindings/display/panel/edt,et-series.txt index f56b99ebd9be..be8684327ee4 100644 --- a/Documentation/devicetree/bindings/display/panel/edt,et-series.txt +++ b/Documentation/devicetree/bindings/display/panel/edt,et-series.txt @@ -6,6 +6,22 @@ Display bindings for EDT Display Technology Corp. Displays which are compatible with the simple-panel binding, which is specified in simple-panel.txt +3,5" QVGA TFT Panels +-------------------- ++-----------------+---------------------+-------------------------------------+ +| Identifier | compatbile | description | ++=================+=====================+=====================================+ +| ET035012DM6 | edt,et035012dm6 | 3.5" QVGA TFT LCD panel | ++-----------------+---------------------+-------------------------------------+ + +4,3" WVGA TFT Panels +-------------------- + ++-----------------+---------------------+-------------------------------------+ +| Identifier | compatbile | description | ++=================+=====================+=====================================+ +| ETM0430G0DH6 | edt,etm0430g0dh6 | 480x272 TFT Display | ++-----------------+---------------------+-------------------------------------+ 5,7" WVGA TFT Panels -------------------- diff --git a/Documentation/devicetree/bindings/display/panel/evervision,vgg804821.txt b/Documentation/devicetree/bindings/display/panel/evervision,vgg804821.txt new file mode 100644 index 000000000000..82d22e191ac3 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/evervision,vgg804821.txt @@ -0,0 +1,12 @@ +Evervision Electronics Co. Ltd. VGG804821 5.0" WVGA TFT LCD Panel + +Required properties: +- compatible: should be "evervision,vgg804821" +- power-supply: See simple-panel.txt + +Optional properties: +- backlight: See simple-panel.txt +- enable-gpios: See simple-panel.txt + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/Documentation/devicetree/bindings/display/panel/friendlyarm,hd702e.txt b/Documentation/devicetree/bindings/display/panel/friendlyarm,hd702e.txt new file mode 100644 index 000000000000..6c9156fc3478 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/friendlyarm,hd702e.txt @@ -0,0 +1,32 @@ +FriendlyELEC HD702E 800x1280 LCD panel + +HD702E lcd is FriendlyELEC developed eDP LCD panel with 800x1280 +resolution. It has built in Goodix, GT9271 captive touchscreen +with backlight adjustable via PWM. + +Required properties: +- compatible: should be "friendlyarm,hd702e" +- power-supply: regulator to provide the supply voltage + +Optional properties: +- backlight: phandle of the backlight device attached to the panel + +Optional nodes: +- Video port for LCD panel input. + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. + +Example: + + panel { + compatible ="friendlyarm,hd702e", "simple-panel"; + backlight = <&backlight>; + power-supply = <&vcc3v3_sys>; + + port { + panel_in_edp: endpoint { + remote-endpoint = <&edp_out_panel>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/display/panel/osddisplays,osd101t2045-53ts.txt b/Documentation/devicetree/bindings/display/panel/osddisplays,osd101t2045-53ts.txt new file mode 100644 index 000000000000..85c0b2cacfda --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/osddisplays,osd101t2045-53ts.txt @@ -0,0 +1,11 @@ +One Stop Displays OSD101T2045-53TS 10.1" 1920x1200 panel + +Required properties: +- compatible: should be "osddisplays,osd101t2045-53ts" +- power-supply: as specified in the base binding + +Optional properties: +- backlight: as specified in the base binding + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/Documentation/devicetree/bindings/display/panel/osddisplays,osd101t2587-53ts.txt b/Documentation/devicetree/bindings/display/panel/osddisplays,osd101t2587-53ts.txt new file mode 100644 index 000000000000..9d88e96003fc --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/osddisplays,osd101t2587-53ts.txt @@ -0,0 +1,14 @@ +One Stop Displays OSD101T2587-53TS 10.1" 1920x1200 panel + +The panel is similar to OSD101T2045-53TS, but it needs additional +MIPI_DSI_TURN_ON_PERIPHERAL message from the host. + +Required properties: +- compatible: should be "osddisplays,osd101t2587-53ts" +- power-supply: as specified in the base binding + +Optional properties: +- backlight: as specified in the base binding + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.txt b/Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.txt new file mode 100644 index 000000000000..9fb9ebeef8e4 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.txt @@ -0,0 +1,33 @@ +Samsung s6e63m0 AMOLED LCD panel + +Required properties: + - compatible: "samsung,s6e63m0" + - reset-gpios: GPIO spec for reset pin + - vdd3-supply: VDD regulator + - vci-supply: VCI regulator + +The panel must obey rules for SPI slave device specified in document [1]. + +The device node can contain one 'port' child node with one child +'endpoint' node, according to the bindings defined in [2]. This +node should describe panel's video bus. + +[1]: Documentation/devicetree/bindings/spi/spi-bus.txt +[2]: Documentation/devicetree/bindings/media/video-interfaces.txt + +Example: + + s6e63m0: display@0 { + compatible = "samsung,s6e63m0"; + reg = <0>; + reset-gpio = <&mp05 5 1>; + vdd3-supply = <&ldo12_reg>; + vci-supply = <&ldo11_reg>; + spi-max-frequency = <1200000>; + + port { + lcd_ep: endpoint { + remote-endpoint = <&fimd_ep>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/display/panel/tfc,s9700rtwv43tr-01b.txt b/Documentation/devicetree/bindings/display/panel/tfc,s9700rtwv43tr-01b.txt new file mode 100644 index 000000000000..dfb572f085eb --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/tfc,s9700rtwv43tr-01b.txt @@ -0,0 +1,15 @@ +TFC S9700RTWV43TR-01B 7" Three Five Corp 800x480 LCD panel with +resistive touch + +The panel is found on TI AM335x-evm. + +Required properties: +- compatible: should be "tfc,s9700rtwv43tr-01b" +- power-supply: See panel-common.txt + +Optional properties: +- enable-gpios: GPIO pin to enable or disable the panel, if there is one +- backlight: phandle of the backlight device attached to the panel + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/Documentation/devicetree/bindings/display/panel/vl050_8048nt_c01.txt b/Documentation/devicetree/bindings/display/panel/vl050_8048nt_c01.txt new file mode 100644 index 000000000000..b42bf06bbd99 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/vl050_8048nt_c01.txt @@ -0,0 +1,12 @@ +VXT 800x480 color TFT LCD panel + +Required properties: +- compatible: should be "vxt,vl050-8048nt-c01" +- power-supply: as specified in the base binding + +Optional properties: +- backlight: as specified in the base binding +- enable-gpios: as specified in the base binding + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt b/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt index 3eb1b48b47dd..60c54da4e526 100644 --- a/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt +++ b/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt @@ -40,6 +40,8 @@ Mandatory nodes specific to STM32 DSI: - panel or bridge node: A node containing the panel or bridge description as documented in [6]. - port: panel or bridge port node, connected to the DSI output port (port@1). +Optional properties: +- phy-dsi-supply: phandle of the regulator that provides the supply voltage. Note: You can find more documentation in the following references [1] Documentation/devicetree/bindings/clock/clock-bindings.txt @@ -101,6 +103,7 @@ Example 2: DSI panel clock-names = "pclk", "ref"; resets = <&rcc STM32F4_APB2_RESET(DSI)>; reset-names = "apb"; + phy-dsi-supply = <®18>; ports { #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt index 1b1a74129141..e5ad3b2afe17 100644 --- a/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt +++ b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt @@ -15,6 +15,7 @@ Required properties: + "arm,mali-t860" + "arm,mali-t880" * which must be preceded by one of the following vendor specifics: + + "allwinner,sun50i-h6-mali" + "amlogic,meson-gxm-mali" + "rockchip,rk3288-mali" + "rockchip,rk3399-mali" @@ -31,21 +32,36 @@ Optional properties: - clocks : Phandle to clock for the Mali Midgard device. +- clock-names : Specify the names of the clocks specified in clocks + when multiple clocks are present. + * core: clock driving the GPU itself (When only one clock is present, + assume it's this clock.) + * bus: bus clock for the GPU + - mali-supply : Phandle to regulator for the Mali device. Refer to Documentation/devicetree/bindings/regulator/regulator.txt for details. - operating-points-v2 : Refer to Documentation/devicetree/bindings/opp/opp.txt for details. +- #cooling-cells: Refer to Documentation/devicetree/bindings/thermal/thermal.txt + for details. + - resets : Phandle of the GPU reset line. Vendor-specific bindings ------------------------ The Mali GPU is integrated very differently from one SoC to -another. In order to accomodate those differences, you have the option +another. In order to accommodate those differences, you have the option to specify one more vendor-specific compatible, among: +- "allwinner,sun50i-h6-mali" + Required properties: + - clocks : phandles to core and bus clocks + - clock-names : must contain "core" and "bus" + - resets: phandle to GPU reset line + - "amlogic,meson-gxm-mali" Required properties: - resets : Should contain phandles of : @@ -65,6 +81,7 @@ gpu@ffa30000 { mali-supply = <&vdd_gpu>; operating-points-v2 = <&gpu_opp_table>; power-domains = <&power RK3288_PD_GPU>; + #cooling-cells = <2>; }; gpu_opp_table: opp_table0 { diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 33a65a45e319..f0bcff033ecc 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -287,6 +287,8 @@ patternProperties: description: Everest Semiconductor Co. Ltd. "^everspin,.*": description: Everspin Technologies, Inc. + "^evervision,.*": + description: Evervision Electronics Co. Ltd. "^exar,.*": description: Exar Corporation "^excito,.*": @@ -849,6 +851,8 @@ patternProperties: description: Shenzhen Techstar Electronics Co., Ltd. "^terasic,.*": description: Terasic Inc. + "^tfc,.*": + description: Three Five Corp "^thine,.*": description: THine Electronics, Inc. "^ti,.*": @@ -923,6 +927,8 @@ patternProperties: description: Voipac Technologies s.r.o. "^vot,.*": description: Vision Optical Technology Co., Ltd. + "^vxt,.*": + description: VXT Ltd "^wd,.*": description: Western Digital Corp. "^wetek,.*": diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst index 54a696d961a7..c8ebd4f66a6a 100644 --- a/Documentation/gpu/drm-mm.rst +++ b/Documentation/gpu/drm-mm.rst @@ -79,7 +79,6 @@ count for the TTM, which will call your initialization function. See the radeon_ttm.c file for an example of usage. - The Graphics Execution Manager (GEM) ==================================== @@ -380,6 +379,39 @@ GEM CMA Helper Functions Reference .. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c :export: +VRAM Helper Function Reference +============================== + +.. kernel-doc:: drivers/gpu/drm/drm_vram_helper_common.c + :doc: overview + +.. kernel-doc:: include/drm/drm_gem_vram_helper.h + :internal: + +GEM VRAM Helper Functions Reference +----------------------------------- + +.. kernel-doc:: drivers/gpu/drm/drm_gem_vram_helper.c + :doc: overview + +.. kernel-doc:: include/drm/drm_gem_vram_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_gem_vram_helper.c + :export: + +VRAM MM Helper Functions Reference +---------------------------------- + +.. kernel-doc:: drivers/gpu/drm/drm_vram_mm_helper.c + :doc: overview + +.. kernel-doc:: include/drm/drm_vram_mm_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_vram_mm_helper.c + :export: + VMA Offset Manager ================== diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index c9fd23efd957..05874d09820c 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -85,16 +85,18 @@ leads to a few additional requirements: - The userspace side must be fully reviewed and tested to the standards of that userspace project. For e.g. mesa this means piglit testcases and review on the mailing list. This is again to ensure that the new interface actually gets the - job done. + job done. The userspace-side reviewer should also provide at least an + Acked-by on the kernel uAPI patch indicating that they've looked at how the + kernel side is implementing the new feature being used. - The userspace patches must be against the canonical upstream, not some vendor fork. This is to make sure that no one cheats on the review and testing requirements by doing a quick fork. - The kernel patch can only be merged after all the above requirements are met, - but it **must** be merged **before** the userspace patches land. uAPI always flows - from the kernel, doing things the other way round risks divergence of the uAPI - definitions and header files. + but it **must** be merged to either drm-next or drm-misc-next **before** the + userspace patches land. uAPI always flows from the kernel, doing things the + other way round risks divergence of the uAPI definitions and header files. These are fairly steep requirements, but have grown out from years of shared pain and experience with uAPI added hastily, and almost always regretted about diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 1528ad2d598b..66f05f4e469f 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -10,25 +10,6 @@ graphics subsystem useful as newbie projects. Or for slow rainy days. Subsystem-wide refactorings =========================== -De-midlayer drivers -------------------- - -With the recent ``drm_bus`` cleanup patches for 3.17 it is no longer required -to have a ``drm_bus`` structure set up. Drivers can directly set up the -``drm_device`` structure instead of relying on bus methods in ``drm_usb.c`` -and ``drm_pci.c``. The goal is to get rid of the driver's ``->load`` / -``->unload`` callbacks and open-code the load/unload sequence properly, using -the new two-stage ``drm_device`` setup/teardown. - -Once all existing drivers are converted we can also remove those bus support -files for USB and platform devices. - -All you need is a GPU for a non-converted driver (currently almost all of -them, but also all the virtual ones used by KVM, so everyone qualifies). - -Contact: Daniel Vetter, Thierry Reding, respective driver maintainers - - Remove custom dumb_map_offset implementations --------------------------------------------- @@ -300,6 +281,14 @@ it to use drm_mode_hsync() instead. Contact: Sean Paul +drm_fb_helper tasks +------------------- + +- drm_fb_helper_restore_fbdev_mode_unlocked() should call restore_fbdev_mode() + not the _force variant so it can bail out if there is a master. But first + these igt tests need to be fixed: kms_fbcon_fbt@psr and + kms_fbcon_fbt@psr-suspend. + Core refactorings ================= diff --git a/MAINTAINERS b/MAINTAINERS index 429c6c624861..eb274ac5b834 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5413,6 +5413,7 @@ T: git git://anongit.freedesktop.org/drm/drm-misc DRM PANEL DRIVERS M: Thierry Reding +R: Sam Ravnborg L: dri-devel@lists.freedesktop.org T: git git://anongit.freedesktop.org/drm/drm-misc S: Maintained @@ -5441,7 +5442,6 @@ F: Documentation/gpu/xen-front.rst DRM TTM SUBSYSTEM M: Christian Koenig M: Huang Rui -M: Junwei Zhang T: git git://people.freedesktop.org/~agd5f/linux S: Maintained L: dri-devel@lists.freedesktop.org diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 7c858020d14b..f4104a21b069 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -90,6 +90,10 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma) dmabuf = file->private_data; + /* check if buffer supports mmap */ + if (!dmabuf->ops->mmap) + return -EINVAL; + /* check for overflowing the buffer's size */ if (vma->vm_pgoff + vma_pages(vma) > dmabuf->size >> PAGE_SHIFT) @@ -404,8 +408,7 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info) || !exp_info->ops || !exp_info->ops->map_dma_buf || !exp_info->ops->unmap_dma_buf - || !exp_info->ops->release - || !exp_info->ops->mmap)) { + || !exp_info->ops->release)) { return ERR_PTR(-EINVAL); } @@ -573,6 +576,7 @@ struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, list_add(&attach->node, &dmabuf->attachments); mutex_unlock(&dmabuf->lock); + return attach; err_attach: @@ -595,6 +599,9 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach) if (WARN_ON(!dmabuf || !attach)) return; + if (attach->sgt) + dmabuf->ops->unmap_dma_buf(attach, attach->sgt, attach->dir); + mutex_lock(&dmabuf->lock); list_del(&attach->node); if (dmabuf->ops->detach) @@ -630,10 +637,27 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach, if (WARN_ON(!attach || !attach->dmabuf)) return ERR_PTR(-EINVAL); + if (attach->sgt) { + /* + * Two mappings with different directions for the same + * attachment are not allowed. + */ + if (attach->dir != direction && + attach->dir != DMA_BIDIRECTIONAL) + return ERR_PTR(-EBUSY); + + return attach->sgt; + } + sg_table = attach->dmabuf->ops->map_dma_buf(attach, direction); if (!sg_table) sg_table = ERR_PTR(-ENOMEM); + if (!IS_ERR(sg_table) && attach->dmabuf->ops->cache_sgt_mapping) { + attach->sgt = sg_table; + attach->dir = direction; + } + return sg_table; } EXPORT_SYMBOL_GPL(dma_buf_map_attachment); @@ -657,8 +681,10 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach, if (WARN_ON(!attach || !attach->dmabuf || !sg_table)) return; - attach->dmabuf->ops->unmap_dma_buf(attach, sg_table, - direction); + if (attach->sgt == sg_table) + return; + + attach->dmabuf->ops->unmap_dma_buf(attach, sg_table, direction); } EXPORT_SYMBOL_GPL(dma_buf_unmap_attachment); @@ -906,6 +932,10 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma, if (WARN_ON(!dmabuf || !vma)) return -EINVAL; + /* check if buffer supports mmap */ + if (!dmabuf->ops->mmap) + return -EINVAL; + /* check for offset overflow */ if (pgoff + vma_pages(vma) < pgoff) return -EOVERFLOW; @@ -1068,6 +1098,7 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused) fence->ops->get_driver_name(fence), fence->ops->get_timeline_name(fence), dma_fence_is_signaled(fence) ? "" : "un"); + dma_fence_put(fence); } rcu_read_unlock(); diff --git a/drivers/dma-buf/sync_debug.c b/drivers/dma-buf/sync_debug.c index c0abf37df88b..434a66518e0d 100644 --- a/drivers/dma-buf/sync_debug.c +++ b/drivers/dma-buf/sync_debug.c @@ -197,29 +197,3 @@ static __init int sync_debugfs_init(void) return 0; } late_initcall(sync_debugfs_init); - -#define DUMP_CHUNK 256 -static char sync_dump_buf[64 * 1024]; -void sync_dump(void) -{ - struct seq_file s = { - .buf = sync_dump_buf, - .size = sizeof(sync_dump_buf) - 1, - }; - int i; - - sync_info_debugfs_show(&s, NULL); - - for (i = 0; i < s.count; i += DUMP_CHUNK) { - if ((s.count - i) > DUMP_CHUNK) { - char c = s.buf[i + DUMP_CHUNK]; - - s.buf[i + DUMP_CHUNK] = 0; - pr_cont("%s", s.buf + i); - s.buf[i + DUMP_CHUNK] = c; - } else { - s.buf[s.count] = 0; - pr_cont("%s", s.buf + i); - } - } -} diff --git a/drivers/dma-buf/sync_debug.h b/drivers/dma-buf/sync_debug.h index 05e33f937ad0..6176e52ba2d7 100644 --- a/drivers/dma-buf/sync_debug.h +++ b/drivers/dma-buf/sync_debug.h @@ -68,6 +68,5 @@ void sync_timeline_debug_add(struct sync_timeline *obj); void sync_timeline_debug_remove(struct sync_timeline *obj); void sync_file_debug_add(struct sync_file *fence); void sync_file_debug_remove(struct sync_file *fence); -void sync_dump(void); #endif /* _LINUX_SYNC_H */ diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 36f900d63979..b62f40cc9691 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -161,6 +161,13 @@ config DRM_TTM GPU memory types. Will be enabled automatically if a device driver uses it. +config DRM_VRAM_HELPER + tristate + depends on DRM + select DRM_TTM + help + Helpers for VRAM memory management + config DRM_GEM_CMA_HELPER bool depends on DRM diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 72f5036d9bfa..4c3dc4268b65 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -32,6 +32,11 @@ drm-$(CONFIG_AGP) += drm_agpsupport.o drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o +drm_vram_helper-y := drm_gem_vram_helper.o \ + drm_vram_helper_common.o \ + drm_vram_mm_helper.o +obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o + drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_dsc.o drm_probe_helper.o \ drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \ drm_kms_helper_common.o drm_dp_dual_mode_helper.o \ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index cc8ad3831982..9f282e971197 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3341,8 +3341,6 @@ static int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev, if (!ring || !ring->sched.thread) continue; - drm_sched_stop(&ring->sched); - /* after all hw jobs are reset, hw fence is meaningless, so force_completion */ amdgpu_fence_driver_force_completion(ring); } @@ -3350,8 +3348,7 @@ static int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev, if(job) drm_sched_increase_karma(&job->base); - - + /* Don't suspend on bare metal if we are not going to HW reset the ASIC */ if (!amdgpu_sriov_vf(adev)) { if (!need_full_reset) @@ -3489,38 +3486,21 @@ end: return r; } -static void amdgpu_device_post_asic_reset(struct amdgpu_device *adev, - struct amdgpu_job *job) +static bool amdgpu_device_lock_adev(struct amdgpu_device *adev, bool trylock) { - int i; + if (trylock) { + if (!mutex_trylock(&adev->lock_reset)) + return false; + } else + mutex_lock(&adev->lock_reset); - for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { - struct amdgpu_ring *ring = adev->rings[i]; - - if (!ring || !ring->sched.thread) - continue; - - if (!adev->asic_reset_res) - drm_sched_resubmit_jobs(&ring->sched); - - drm_sched_start(&ring->sched, !adev->asic_reset_res); - } - - if (!amdgpu_device_has_dc_support(adev)) { - drm_helper_resume_force_mode(adev->ddev); - } - - adev->asic_reset_res = 0; -} - -static void amdgpu_device_lock_adev(struct amdgpu_device *adev) -{ - mutex_lock(&adev->lock_reset); atomic_inc(&adev->gpu_reset_counter); adev->in_gpu_reset = 1; /* Block kfd: SRIOV would do it separately */ if (!amdgpu_sriov_vf(adev)) amdgpu_amdkfd_pre_reset(adev); + + return true; } static void amdgpu_device_unlock_adev(struct amdgpu_device *adev) @@ -3548,40 +3528,42 @@ static void amdgpu_device_unlock_adev(struct amdgpu_device *adev) int amdgpu_device_gpu_recover(struct amdgpu_device *adev, struct amdgpu_job *job) { - int r; - struct amdgpu_hive_info *hive = NULL; - bool need_full_reset = false; - struct amdgpu_device *tmp_adev = NULL; struct list_head device_list, *device_list_handle = NULL; + bool need_full_reset, job_signaled; + struct amdgpu_hive_info *hive = NULL; + struct amdgpu_device *tmp_adev = NULL; + int i, r = 0; + need_full_reset = job_signaled = false; INIT_LIST_HEAD(&device_list); dev_info(adev->dev, "GPU reset begin!\n"); + hive = amdgpu_get_xgmi_hive(adev, false); + /* - * In case of XGMI hive disallow concurrent resets to be triggered - * by different nodes. No point also since the one node already executing - * reset will also reset all the other nodes in the hive. + * Here we trylock to avoid chain of resets executing from + * either trigger by jobs on different adevs in XGMI hive or jobs on + * different schedulers for same device while this TO handler is running. + * We always reset all schedulers for device and all devices for XGMI + * hive so that should take care of them too. */ - hive = amdgpu_get_xgmi_hive(adev, 0); - if (hive && adev->gmc.xgmi.num_physical_nodes > 1 && - !mutex_trylock(&hive->reset_lock)) + + if (hive && !mutex_trylock(&hive->reset_lock)) { + DRM_INFO("Bailing on TDR for s_job:%llx, hive: %llx as another already in progress", + job->base.id, hive->hive_id); return 0; + } /* Start with adev pre asic reset first for soft reset check.*/ - amdgpu_device_lock_adev(adev); - r = amdgpu_device_pre_asic_reset(adev, - job, - &need_full_reset); - if (r) { - /*TODO Should we stop ?*/ - DRM_ERROR("GPU pre asic reset failed with err, %d for drm dev, %s ", - r, adev->ddev->unique); - adev->asic_reset_res = r; + if (!amdgpu_device_lock_adev(adev, !hive)) { + DRM_INFO("Bailing on TDR for s_job:%llx, as another already in progress", + job->base.id); + return 0; } /* Build list of devices to reset */ - if (need_full_reset && adev->gmc.xgmi.num_physical_nodes > 1) { + if (adev->gmc.xgmi.num_physical_nodes > 1) { if (!hive) { amdgpu_device_unlock_adev(adev); return -ENODEV; @@ -3598,13 +3580,56 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, device_list_handle = &device_list; } + /* block all schedulers and reset given job's ring */ + list_for_each_entry(tmp_adev, device_list_handle, gmc.xgmi.head) { + for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { + struct amdgpu_ring *ring = tmp_adev->rings[i]; + + if (!ring || !ring->sched.thread) + continue; + + drm_sched_stop(&ring->sched, &job->base); + } + } + + + /* + * Must check guilty signal here since after this point all old + * HW fences are force signaled. + * + * job->base holds a reference to parent fence + */ + if (job && job->base.s_fence->parent && + dma_fence_is_signaled(job->base.s_fence->parent)) + job_signaled = true; + + if (!amdgpu_device_ip_need_full_reset(adev)) + device_list_handle = &device_list; + + if (job_signaled) { + dev_info(adev->dev, "Guilty job already signaled, skipping HW reset"); + goto skip_hw_reset; + } + + + /* Guilty job will be freed after this*/ + r = amdgpu_device_pre_asic_reset(adev, + job, + &need_full_reset); + if (r) { + /*TODO Should we stop ?*/ + DRM_ERROR("GPU pre asic reset failed with err, %d for drm dev, %s ", + r, adev->ddev->unique); + adev->asic_reset_res = r; + } + retry: /* Rest of adevs pre asic reset from XGMI hive. */ list_for_each_entry(tmp_adev, device_list_handle, gmc.xgmi.head) { if (tmp_adev == adev) continue; - amdgpu_device_lock_adev(tmp_adev); + amdgpu_device_lock_adev(tmp_adev, false); r = amdgpu_device_pre_asic_reset(tmp_adev, NULL, &need_full_reset); @@ -3628,9 +3653,28 @@ retry: /* Rest of adevs pre asic reset from XGMI hive. */ goto retry; } +skip_hw_reset: + /* Post ASIC reset for all devs .*/ list_for_each_entry(tmp_adev, device_list_handle, gmc.xgmi.head) { - amdgpu_device_post_asic_reset(tmp_adev, tmp_adev == adev ? job : NULL); + for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { + struct amdgpu_ring *ring = tmp_adev->rings[i]; + + if (!ring || !ring->sched.thread) + continue; + + /* No point to resubmit jobs if we didn't HW reset*/ + if (!tmp_adev->asic_reset_res && !job_signaled) + drm_sched_resubmit_jobs(&ring->sched); + + drm_sched_start(&ring->sched, !tmp_adev->asic_reset_res); + } + + if (!amdgpu_device_has_dc_support(tmp_adev) && !job_signaled) { + drm_helper_resume_force_mode(tmp_adev->ddev); + } + + tmp_adev->asic_reset_res = 0; if (r) { /* bad news, how to tell it to userspace ? */ @@ -3643,7 +3687,7 @@ retry: /* Rest of adevs pre asic reset from XGMI hive. */ amdgpu_device_unlock_adev(tmp_adev); } - if (hive && adev->gmc.xgmi.num_physical_nodes > 1) + if (hive) mutex_unlock(&hive->reset_lock); if (r) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c index e47609218839..2e2869299a84 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c @@ -121,6 +121,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev, struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **gobj_p) { + const struct drm_format_info *info; struct amdgpu_device *adev = rfbdev->adev; struct drm_gem_object *gobj = NULL; struct amdgpu_bo *abo = NULL; @@ -131,7 +132,8 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev, int height = mode_cmd->height; u32 cpp; - cpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0); + info = drm_get_format_info(adev->ddev, mode_cmd); + cpp = info->cpp[0]; /* need to align pitch with crtc limits */ mode_cmd->pitches[0] = amdgpu_align_pitch(adev, mode_cmd->width, cpp, diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c index 56aad288666e..d6690e016f0b 100644 --- a/drivers/gpu/drm/arm/malidp_crtc.c +++ b/drivers/gpu/drm/arm/malidp_crtc.c @@ -463,23 +463,6 @@ static struct drm_crtc_state *malidp_crtc_duplicate_state(struct drm_crtc *crtc) return &state->base; } -static void malidp_crtc_reset(struct drm_crtc *crtc) -{ - struct malidp_crtc_state *state = NULL; - - if (crtc->state) { - state = to_malidp_crtc_state(crtc->state); - __drm_atomic_helper_crtc_destroy_state(crtc->state); - } - - kfree(state); - state = kzalloc(sizeof(*state), GFP_KERNEL); - if (state) { - crtc->state = &state->base; - crtc->state->crtc = crtc; - } -} - static void malidp_crtc_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -493,6 +476,17 @@ static void malidp_crtc_destroy_state(struct drm_crtc *crtc, kfree(mali_state); } +static void malidp_crtc_reset(struct drm_crtc *crtc) +{ + struct malidp_crtc_state *state = + kzalloc(sizeof(*state), GFP_KERNEL); + + if (crtc->state) + malidp_crtc_destroy_state(crtc, crtc->state); + + __drm_atomic_helper_crtc_reset(crtc, &state->base); +} + static int malidp_crtc_enable_vblank(struct drm_crtc *crtc) { struct malidp_drm *malidp = crtc_to_malidp_device(crtc); diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c index 8df12e9a33bb..53391c0f87eb 100644 --- a/drivers/gpu/drm/arm/malidp_hw.c +++ b/drivers/gpu/drm/arm/malidp_hw.c @@ -382,7 +382,8 @@ static void malidp500_modeset(struct malidp_hw_device *hwdev, struct videomode * int malidp_format_get_bpp(u32 fmt) { - int bpp = drm_format_plane_cpp(fmt, 0) * 8; + const struct drm_format_info *info = drm_format_info(fmt); + int bpp = info->cpp[0] * 8; if (bpp == 0) { switch (fmt) { diff --git a/drivers/gpu/drm/arm/malidp_mw.c b/drivers/gpu/drm/arm/malidp_mw.c index 5f102bdaf841..2e812525025d 100644 --- a/drivers/gpu/drm/arm/malidp_mw.c +++ b/drivers/gpu/drm/arm/malidp_mw.c @@ -158,7 +158,7 @@ malidp_mw_encoder_atomic_check(struct drm_encoder *encoder, return -EINVAL; } - n_planes = drm_format_num_planes(fb->format->format); + n_planes = fb->format->num_planes; for (i = 0; i < n_planes; i++) { struct drm_gem_cma_object *obj = drm_fb_cma_get_gem_obj(fb, i); /* memory write buffers are never rotated */ diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index d42e0ea9a303..07ceb4ee14e3 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c @@ -227,14 +227,13 @@ bool malidp_format_mod_supported(struct drm_device *drm, if (modifier & AFBC_SPLIT) { if (!info->is_yuv) { - if (drm_format_plane_cpp(format, 0) <= 2) { + if (info->cpp[0] <= 2) { DRM_DEBUG_KMS("RGB formats <= 16bpp are not supported with SPLIT\n"); return false; } } - if ((drm_format_horz_chroma_subsampling(format) != 1) || - (drm_format_vert_chroma_subsampling(format) != 1)) { + if ((info->hsub != 1) || (info->vsub != 1)) { if (!(format == DRM_FORMAT_YUV420_10BIT && (map->features & MALIDP_DEVICE_AFBC_YUV_420_10_SUPPORT_SPLIT))) { DRM_DEBUG_KMS("Formats which are sub-sampled should never be split\n"); @@ -244,8 +243,7 @@ bool malidp_format_mod_supported(struct drm_device *drm, } if (modifier & AFBC_CBR) { - if ((drm_format_horz_chroma_subsampling(format) == 1) || - (drm_format_vert_chroma_subsampling(format) == 1)) { + if ((info->hsub == 1) || (info->vsub == 1)) { DRM_DEBUG_KMS("Formats which are not sub-sampled should not have CBR set\n"); return false; } diff --git a/drivers/gpu/drm/armada/armada_fb.c b/drivers/gpu/drm/armada/armada_fb.c index 058ac7d9920f..a2f6472eb482 100644 --- a/drivers/gpu/drm/armada/armada_fb.c +++ b/drivers/gpu/drm/armada/armada_fb.c @@ -87,6 +87,7 @@ struct armada_framebuffer *armada_framebuffer_create(struct drm_device *dev, struct drm_framebuffer *armada_fb_create(struct drm_device *dev, struct drm_file *dfile, const struct drm_mode_fb_cmd2 *mode) { + const struct drm_format_info *info = drm_get_format_info(dev, mode); struct armada_gem_object *obj; struct armada_framebuffer *dfb; int ret; @@ -97,7 +98,7 @@ struct drm_framebuffer *armada_fb_create(struct drm_device *dev, mode->pitches[2]); /* We can only handle a single plane at the moment */ - if (drm_format_num_planes(mode->pixel_format) > 1 && + if (info->num_planes > 1 && (mode->handles[0] != mode->handles[1] || mode->handles[0] != mode->handles[2])) { ret = -EINVAL; diff --git a/drivers/gpu/drm/ast/Kconfig b/drivers/gpu/drm/ast/Kconfig index ac47ecfe7801..829620d5326c 100644 --- a/drivers/gpu/drm/ast/Kconfig +++ b/drivers/gpu/drm/ast/Kconfig @@ -2,9 +2,8 @@ config DRM_AST tristate "AST server chips" depends on DRM && PCI && MMU - select DRM_TTM select DRM_KMS_HELPER - select DRM_TTM + select DRM_VRAM_HELPER help Say yes for experimental AST GPU driver. Do not enable this driver without having a working -modesetting, diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index 3871b39d4dea..3811997e78c4 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -205,13 +205,7 @@ static struct pci_driver ast_pci_driver = { static const struct file_operations ast_fops = { .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - .mmap = ast_mmap, - .poll = drm_poll, - .compat_ioctl = drm_compat_ioctl, - .read = drm_read, + DRM_VRAM_MM_FILE_OPERATIONS }; static struct drm_driver driver = { @@ -228,10 +222,7 @@ static struct drm_driver driver = { .minor = DRIVER_MINOR, .patchlevel = DRIVER_PATCHLEVEL, - .gem_free_object_unlocked = ast_gem_free_object, - .dumb_create = ast_dumb_create, - .dumb_map_offset = ast_dumb_mmap_offset, - + DRM_GEM_VRAM_DRIVER }; static int __init ast_init(void) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 1cf0c75e411d..b6cac9511796 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -31,13 +31,10 @@ #include #include -#include -#include -#include -#include -#include - #include +#include + +#include #include #include @@ -103,10 +100,6 @@ struct ast_private { int fb_mtrr; - struct { - struct ttm_bo_device bdev; - } ttm; - struct drm_gem_object *cursor_cache; uint64_t cursor_cache_gpu_addr; /* Acces to this cache is protected by the crtc->mutex of the only crtc @@ -263,7 +256,6 @@ struct ast_fbdev { struct ast_framebuffer afb; void *sysram; int size; - struct ttm_bo_kmap_obj mapping; int x1, y1, x2, y2; /* dirty rect */ spinlock_t dirty_lock; }; @@ -321,73 +313,16 @@ void ast_fbdev_fini(struct drm_device *dev); void ast_fbdev_set_suspend(struct drm_device *dev, int state); void ast_fbdev_set_base(struct ast_private *ast, unsigned long gpu_addr); -struct ast_bo { - struct ttm_buffer_object bo; - struct ttm_placement placement; - struct ttm_bo_kmap_obj kmap; - struct drm_gem_object gem; - struct ttm_place placements[3]; - int pin_count; -}; -#define gem_to_ast_bo(gobj) container_of((gobj), struct ast_bo, gem) - -static inline struct ast_bo * -ast_bo(struct ttm_buffer_object *bo) -{ - return container_of(bo, struct ast_bo, bo); -} - - -#define to_ast_obj(x) container_of(x, struct ast_gem_object, base) - #define AST_MM_ALIGN_SHIFT 4 #define AST_MM_ALIGN_MASK ((1 << AST_MM_ALIGN_SHIFT) - 1) -extern int ast_dumb_create(struct drm_file *file, - struct drm_device *dev, - struct drm_mode_create_dumb *args); - -extern void ast_gem_free_object(struct drm_gem_object *obj); -extern int ast_dumb_mmap_offset(struct drm_file *file, - struct drm_device *dev, - uint32_t handle, - uint64_t *offset); - int ast_mm_init(struct ast_private *ast); void ast_mm_fini(struct ast_private *ast); -int ast_bo_create(struct drm_device *dev, int size, int align, - uint32_t flags, struct ast_bo **pastbo); - int ast_gem_create(struct drm_device *dev, u32 size, bool iskernel, struct drm_gem_object **obj); -int ast_bo_pin(struct ast_bo *bo, u32 pl_flag, u64 *gpu_addr); -int ast_bo_unpin(struct ast_bo *bo); - -static inline int ast_bo_reserve(struct ast_bo *bo, bool no_wait) -{ - int ret; - - ret = ttm_bo_reserve(&bo->bo, true, no_wait, NULL); - if (ret) { - if (ret != -ERESTARTSYS && ret != -EBUSY) - DRM_ERROR("reserve failed %p\n", bo); - return ret; - } - return 0; -} - -static inline void ast_bo_unreserve(struct ast_bo *bo) -{ - ttm_bo_unreserve(&bo->bo); -} - -void ast_ttm_placement(struct ast_bo *bo, int domain); -int ast_bo_push_sysram(struct ast_bo *bo); -int ast_mmap(struct file *filp, struct vm_area_struct *vma); - /* ast post */ void ast_enable_vga(struct drm_device *dev); void ast_enable_mmio(struct drm_device *dev); diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c index e718d0f60d6b..05f45222b702 100644 --- a/drivers/gpu/drm/ast/ast_fb.c +++ b/drivers/gpu/drm/ast/ast_fb.c @@ -49,25 +49,25 @@ static void ast_dirty_update(struct ast_fbdev *afbdev, { int i; struct drm_gem_object *obj; - struct ast_bo *bo; + struct drm_gem_vram_object *gbo; int src_offset, dst_offset; int bpp = afbdev->afb.base.format->cpp[0]; int ret = -EBUSY; + u8 *dst; bool unmap = false; bool store_for_later = false; int x2, y2; unsigned long flags; obj = afbdev->afb.obj; - bo = gem_to_ast_bo(obj); + gbo = drm_gem_vram_of_gem(obj); - /* - * try and reserve the BO, if we fail with busy - * then the BO is being moved and we should - * store up the damage until later. + /* Try to lock the BO. If we fail with -EBUSY then + * the BO is being moved and we should store up the + * damage until later. */ if (drm_can_sleep()) - ret = ast_bo_reserve(bo, true); + ret = drm_gem_vram_lock(gbo, true); if (ret) { if (ret != -EBUSY) return; @@ -101,25 +101,32 @@ static void ast_dirty_update(struct ast_fbdev *afbdev, afbdev->x2 = afbdev->y2 = 0; spin_unlock_irqrestore(&afbdev->dirty_lock, flags); - if (!bo->kmap.virtual) { - ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); - if (ret) { + dst = drm_gem_vram_kmap(gbo, false, NULL); + if (IS_ERR(dst)) { + DRM_ERROR("failed to kmap fb updates\n"); + goto out; + } else if (!dst) { + dst = drm_gem_vram_kmap(gbo, true, NULL); + if (IS_ERR(dst)) { DRM_ERROR("failed to kmap fb updates\n"); - ast_bo_unreserve(bo); - return; + goto out; } unmap = true; } + for (i = y; i <= y2; i++) { /* assume equal stride for now */ - src_offset = dst_offset = i * afbdev->afb.base.pitches[0] + (x * bpp); - memcpy_toio(bo->kmap.virtual + src_offset, afbdev->sysram + src_offset, (x2 - x + 1) * bpp); - + src_offset = dst_offset = + i * afbdev->afb.base.pitches[0] + (x * bpp); + memcpy_toio(dst + dst_offset, afbdev->sysram + src_offset, + (x2 - x + 1) * bpp); } - if (unmap) - ttm_bo_kunmap(&bo->kmap); - ast_bo_unreserve(bo); + if (unmap) + drm_gem_vram_kunmap(gbo); + +out: + drm_gem_vram_unlock(gbo); } static void ast_fillrect(struct fb_info *info, diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 2854399856ba..4c7e31cb45ff 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -593,7 +593,7 @@ int ast_gem_create(struct drm_device *dev, u32 size, bool iskernel, struct drm_gem_object **obj) { - struct ast_bo *astbo; + struct drm_gem_vram_object *gbo; int ret; *obj = NULL; @@ -602,80 +602,13 @@ int ast_gem_create(struct drm_device *dev, if (size == 0) return -EINVAL; - ret = ast_bo_create(dev, size, 0, 0, &astbo); - if (ret) { + gbo = drm_gem_vram_create(dev, &dev->vram_mm->bdev, size, 0, false); + if (IS_ERR(gbo)) { + ret = PTR_ERR(gbo); if (ret != -ERESTARTSYS) DRM_ERROR("failed to allocate GEM object\n"); return ret; } - *obj = &astbo->gem; + *obj = &gbo->gem; return 0; } - -int ast_dumb_create(struct drm_file *file, - struct drm_device *dev, - struct drm_mode_create_dumb *args) -{ - int ret; - struct drm_gem_object *gobj; - u32 handle; - - args->pitch = args->width * ((args->bpp + 7) / 8); - args->size = args->pitch * args->height; - - ret = ast_gem_create(dev, args->size, false, - &gobj); - if (ret) - return ret; - - ret = drm_gem_handle_create(file, gobj, &handle); - drm_gem_object_put_unlocked(gobj); - if (ret) - return ret; - - args->handle = handle; - return 0; -} - -static void ast_bo_unref(struct ast_bo **bo) -{ - if ((*bo) == NULL) - return; - ttm_bo_put(&((*bo)->bo)); - *bo = NULL; -} - -void ast_gem_free_object(struct drm_gem_object *obj) -{ - struct ast_bo *ast_bo = gem_to_ast_bo(obj); - - ast_bo_unref(&ast_bo); -} - - -static inline u64 ast_bo_mmap_offset(struct ast_bo *bo) -{ - return drm_vma_node_offset_addr(&bo->bo.vma_node); -} -int -ast_dumb_mmap_offset(struct drm_file *file, - struct drm_device *dev, - uint32_t handle, - uint64_t *offset) -{ - struct drm_gem_object *obj; - struct ast_bo *bo; - - obj = drm_gem_object_lookup(file, handle); - if (obj == NULL) - return -ENOENT; - - bo = gem_to_ast_bo(obj); - *offset = ast_bo_mmap_offset(bo); - - drm_gem_object_put_unlocked(obj); - - return 0; - -} - diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 97fed0627d1c..fb700d620b64 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -521,7 +521,6 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) } } -/* ast is different - we will force move buffers out of VRAM */ static int ast_crtc_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb, int x, int y, int atomic) @@ -529,50 +528,54 @@ static int ast_crtc_do_set_base(struct drm_crtc *crtc, struct ast_private *ast = crtc->dev->dev_private; struct drm_gem_object *obj; struct ast_framebuffer *ast_fb; - struct ast_bo *bo; + struct drm_gem_vram_object *gbo; int ret; - u64 gpu_addr; + s64 gpu_addr; + void *base; - /* push the previous fb to system ram */ if (!atomic && fb) { ast_fb = to_ast_framebuffer(fb); obj = ast_fb->obj; - bo = gem_to_ast_bo(obj); - ret = ast_bo_reserve(bo, false); - if (ret) - return ret; - ast_bo_push_sysram(bo); - ast_bo_unreserve(bo); + gbo = drm_gem_vram_of_gem(obj); + + /* unmap if console */ + if (&ast->fbdev->afb == ast_fb) + drm_gem_vram_kunmap(gbo); + drm_gem_vram_unpin(gbo); } ast_fb = to_ast_framebuffer(crtc->primary->fb); obj = ast_fb->obj; - bo = gem_to_ast_bo(obj); + gbo = drm_gem_vram_of_gem(obj); - ret = ast_bo_reserve(bo, false); + ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM); if (ret) return ret; - - ret = ast_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr); - if (ret) { - ast_bo_unreserve(bo); - return ret; + gpu_addr = drm_gem_vram_offset(gbo); + if (gpu_addr < 0) { + ret = (int)gpu_addr; + goto err_drm_gem_vram_unpin; } if (&ast->fbdev->afb == ast_fb) { /* if pushing console in kmap it */ - ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); - if (ret) + base = drm_gem_vram_kmap(gbo, true, NULL); + if (IS_ERR(base)) { + ret = PTR_ERR(base); DRM_ERROR("failed to kmap fbcon\n"); - else + } else { ast_fbdev_set_base(ast, gpu_addr); + } } - ast_bo_unreserve(bo); ast_set_offset_reg(crtc); ast_set_start_address_crt1(crtc, (u32)gpu_addr); return 0; + +err_drm_gem_vram_unpin: + drm_gem_vram_unpin(gbo); + return ret; } static int ast_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, @@ -618,21 +621,18 @@ static int ast_crtc_mode_set(struct drm_crtc *crtc, static void ast_crtc_disable(struct drm_crtc *crtc) { - int ret; - DRM_DEBUG_KMS("\n"); ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); if (crtc->primary->fb) { + struct ast_private *ast = crtc->dev->dev_private; struct ast_framebuffer *ast_fb = to_ast_framebuffer(crtc->primary->fb); struct drm_gem_object *obj = ast_fb->obj; - struct ast_bo *bo = gem_to_ast_bo(obj); + struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(obj); - ret = ast_bo_reserve(bo, false); - if (ret) - return; - - ast_bo_push_sysram(bo); - ast_bo_unreserve(bo); + /* unmap if console */ + if (&ast->fbdev->afb == ast_fb) + drm_gem_vram_kunmap(gbo); + drm_gem_vram_unpin(gbo); } crtc->primary->fb = NULL; } @@ -918,28 +918,32 @@ static int ast_cursor_init(struct drm_device *dev) int size; int ret; struct drm_gem_object *obj; - struct ast_bo *bo; - uint64_t gpu_addr; + struct drm_gem_vram_object *gbo; + s64 gpu_addr; + void *base; size = (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE) * AST_DEFAULT_HWC_NUM; ret = ast_gem_create(dev, size, true, &obj); if (ret) return ret; - bo = gem_to_ast_bo(obj); - ret = ast_bo_reserve(bo, false); - if (unlikely(ret != 0)) - goto fail; - - ret = ast_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr); - ast_bo_unreserve(bo); + gbo = drm_gem_vram_of_gem(obj); + ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM); if (ret) goto fail; + gpu_addr = drm_gem_vram_offset(gbo); + if (gpu_addr < 0) { + drm_gem_vram_unpin(gbo); + ret = (int)gpu_addr; + goto fail; + } /* kmap the object */ - ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &ast->cache_kmap); - if (ret) + base = drm_gem_vram_kmap_at(gbo, true, NULL, &ast->cache_kmap); + if (IS_ERR(base)) { + ret = PTR_ERR(base); goto fail; + } ast->cursor_cache = obj; ast->cursor_cache_gpu_addr = gpu_addr; @@ -952,7 +956,9 @@ fail: static void ast_cursor_fini(struct drm_device *dev) { struct ast_private *ast = dev->dev_private; - ttm_bo_kunmap(&ast->cache_kmap); + struct drm_gem_vram_object *gbo = + drm_gem_vram_of_gem(ast->cursor_cache); + drm_gem_vram_kunmap_at(gbo, &ast->cache_kmap); drm_gem_object_put_unlocked(ast->cursor_cache); } @@ -1173,8 +1179,8 @@ static int ast_cursor_set(struct drm_crtc *crtc, struct ast_private *ast = crtc->dev->dev_private; struct ast_crtc *ast_crtc = to_ast_crtc(crtc); struct drm_gem_object *obj; - struct ast_bo *bo; - uint64_t gpu_addr; + struct drm_gem_vram_object *gbo; + s64 gpu_addr; u32 csum; int ret; struct ttm_bo_kmap_obj uobj_map; @@ -1193,19 +1199,27 @@ static int ast_cursor_set(struct drm_crtc *crtc, DRM_ERROR("Cannot find cursor object %x for crtc\n", handle); return -ENOENT; } - bo = gem_to_ast_bo(obj); + gbo = drm_gem_vram_of_gem(obj); - ret = ast_bo_reserve(bo, false); + ret = drm_gem_vram_lock(gbo, false); if (ret) goto fail; - ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &uobj_map); - - src = ttm_kmap_obj_virtual(&uobj_map, &src_isiomem); - dst = ttm_kmap_obj_virtual(&ast->cache_kmap, &dst_isiomem); - + memset(&uobj_map, 0, sizeof(uobj_map)); + src = drm_gem_vram_kmap_at(gbo, true, &src_isiomem, &uobj_map); + if (IS_ERR(src)) { + ret = PTR_ERR(src); + goto fail_unlock; + } if (src_isiomem == true) DRM_ERROR("src cursor bo should be in main memory\n"); + + dst = drm_gem_vram_kmap_at(drm_gem_vram_of_gem(ast->cursor_cache), + false, &dst_isiomem, &ast->cache_kmap); + if (IS_ERR(dst)) { + ret = PTR_ERR(dst); + goto fail_unlock; + } if (dst_isiomem == false) DRM_ERROR("dst bo should be in VRAM\n"); @@ -1214,11 +1228,14 @@ static int ast_cursor_set(struct drm_crtc *crtc, /* do data transfer to cursor cache */ csum = copy_cursor_image(src, dst, width, height); + drm_gem_vram_kunmap_at(gbo, &uobj_map); + drm_gem_vram_unlock(gbo); + /* write checksum + signature */ - ttm_bo_kunmap(&uobj_map); - ast_bo_unreserve(bo); { - u8 *dst = (u8 *)ast->cache_kmap.virtual + (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor + AST_HWC_SIZE; + u8 *dst = drm_gem_vram_kmap_at(drm_gem_vram_of_gem(ast->cursor_cache), + false, NULL, &ast->cache_kmap); + dst += (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor + AST_HWC_SIZE; writel(csum, dst); writel(width, dst + AST_HWC_SIGNATURE_SizeX); writel(height, dst + AST_HWC_SIGNATURE_SizeY); @@ -1244,6 +1261,9 @@ static int ast_cursor_set(struct drm_crtc *crtc, drm_gem_object_put_unlocked(obj); return 0; + +fail_unlock: + drm_gem_vram_unlock(gbo); fail: drm_gem_object_put_unlocked(obj); return ret; @@ -1257,7 +1277,9 @@ static int ast_cursor_move(struct drm_crtc *crtc, int x_offset, y_offset; u8 *sig; - sig = (u8 *)ast->cache_kmap.virtual + (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor + AST_HWC_SIZE; + sig = drm_gem_vram_kmap_at(drm_gem_vram_of_gem(ast->cursor_cache), + false, NULL, &ast->cache_kmap); + sig += (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor + AST_HWC_SIZE; writel(x, sig + AST_HWC_SIGNATURE_X); writel(y, sig + AST_HWC_SIGNATURE_Y); diff --git a/drivers/gpu/drm/ast/ast_ttm.c b/drivers/gpu/drm/ast/ast_ttm.c index 75d477b37854..779c53efee8e 100644 --- a/drivers/gpu/drm/ast/ast_ttm.c +++ b/drivers/gpu/drm/ast/ast_ttm.c @@ -26,168 +26,21 @@ * Authors: Dave Airlie */ #include -#include #include "ast_drv.h" -static inline struct ast_private * -ast_bdev(struct ttm_bo_device *bd) -{ - return container_of(bd, struct ast_private, ttm.bdev); -} - -static void ast_bo_ttm_destroy(struct ttm_buffer_object *tbo) -{ - struct ast_bo *bo; - - bo = container_of(tbo, struct ast_bo, bo); - - drm_gem_object_release(&bo->gem); - kfree(bo); -} - -static bool ast_ttm_bo_is_ast_bo(struct ttm_buffer_object *bo) -{ - if (bo->destroy == &ast_bo_ttm_destroy) - return true; - return false; -} - -static int -ast_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, - struct ttm_mem_type_manager *man) -{ - switch (type) { - case TTM_PL_SYSTEM: - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; - man->available_caching = TTM_PL_MASK_CACHING; - man->default_caching = TTM_PL_FLAG_CACHED; - break; - case TTM_PL_VRAM: - man->func = &ttm_bo_manager_func; - man->flags = TTM_MEMTYPE_FLAG_FIXED | - TTM_MEMTYPE_FLAG_MAPPABLE; - man->available_caching = TTM_PL_FLAG_UNCACHED | - TTM_PL_FLAG_WC; - man->default_caching = TTM_PL_FLAG_WC; - break; - default: - DRM_ERROR("Unsupported memory type %u\n", (unsigned)type); - return -EINVAL; - } - return 0; -} - -static void -ast_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl) -{ - struct ast_bo *astbo = ast_bo(bo); - - if (!ast_ttm_bo_is_ast_bo(bo)) - return; - - ast_ttm_placement(astbo, TTM_PL_FLAG_SYSTEM); - *pl = astbo->placement; -} - -static int ast_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp) -{ - struct ast_bo *astbo = ast_bo(bo); - - return drm_vma_node_verify_access(&astbo->gem.vma_node, - filp->private_data); -} - -static int ast_ttm_io_mem_reserve(struct ttm_bo_device *bdev, - struct ttm_mem_reg *mem) -{ - struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; - struct ast_private *ast = ast_bdev(bdev); - - mem->bus.addr = NULL; - mem->bus.offset = 0; - mem->bus.size = mem->num_pages << PAGE_SHIFT; - mem->bus.base = 0; - mem->bus.is_iomem = false; - if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE)) - return -EINVAL; - switch (mem->mem_type) { - case TTM_PL_SYSTEM: - /* system memory */ - return 0; - case TTM_PL_VRAM: - mem->bus.offset = mem->start << PAGE_SHIFT; - mem->bus.base = pci_resource_start(ast->dev->pdev, 0); - mem->bus.is_iomem = true; - break; - default: - return -EINVAL; - break; - } - return 0; -} - -static void ast_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) -{ -} - -static void ast_ttm_backend_destroy(struct ttm_tt *tt) -{ - ttm_tt_fini(tt); - kfree(tt); -} - -static struct ttm_backend_func ast_tt_backend_func = { - .destroy = &ast_ttm_backend_destroy, -}; - - -static struct ttm_tt *ast_ttm_tt_create(struct ttm_buffer_object *bo, - uint32_t page_flags) -{ - struct ttm_tt *tt; - - tt = kzalloc(sizeof(struct ttm_tt), GFP_KERNEL); - if (tt == NULL) - return NULL; - tt->func = &ast_tt_backend_func; - if (ttm_tt_init(tt, bo, page_flags)) { - kfree(tt); - return NULL; - } - return tt; -} - -struct ttm_bo_driver ast_bo_driver = { - .ttm_tt_create = ast_ttm_tt_create, - .init_mem_type = ast_bo_init_mem_type, - .eviction_valuable = ttm_bo_eviction_valuable, - .evict_flags = ast_bo_evict_flags, - .move = NULL, - .verify_access = ast_bo_verify_access, - .io_mem_reserve = &ast_ttm_io_mem_reserve, - .io_mem_free = &ast_ttm_io_mem_free, -}; - int ast_mm_init(struct ast_private *ast) { + struct drm_vram_mm *vmm; int ret; struct drm_device *dev = ast->dev; - struct ttm_bo_device *bdev = &ast->ttm.bdev; - ret = ttm_bo_device_init(&ast->ttm.bdev, - &ast_bo_driver, - dev->anon_inode->i_mapping, - true); - if (ret) { - DRM_ERROR("Error initialising bo driver; %d\n", ret); - return ret; - } - - ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM, - ast->vram_size >> PAGE_SHIFT); - if (ret) { - DRM_ERROR("Failed ttm VRAM init: %d\n", ret); + vmm = drm_vram_helper_alloc_mm( + dev, pci_resource_start(dev->pdev, 0), + ast->vram_size, &drm_gem_vram_mm_funcs); + if (IS_ERR(vmm)) { + ret = PTR_ERR(vmm); + DRM_ERROR("Error initializing VRAM MM; %d\n", ret); return ret; } @@ -203,148 +56,9 @@ void ast_mm_fini(struct ast_private *ast) { struct drm_device *dev = ast->dev; - ttm_bo_device_release(&ast->ttm.bdev); + drm_vram_helper_release_mm(dev); arch_phys_wc_del(ast->fb_mtrr); arch_io_free_memtype_wc(pci_resource_start(dev->pdev, 0), pci_resource_len(dev->pdev, 0)); } - -void ast_ttm_placement(struct ast_bo *bo, int domain) -{ - u32 c = 0; - unsigned i; - - bo->placement.placement = bo->placements; - bo->placement.busy_placement = bo->placements; - if (domain & TTM_PL_FLAG_VRAM) - bo->placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM; - if (domain & TTM_PL_FLAG_SYSTEM) - bo->placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM; - if (!c) - bo->placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM; - bo->placement.num_placement = c; - bo->placement.num_busy_placement = c; - for (i = 0; i < c; ++i) { - bo->placements[i].fpfn = 0; - bo->placements[i].lpfn = 0; - } -} - -int ast_bo_create(struct drm_device *dev, int size, int align, - uint32_t flags, struct ast_bo **pastbo) -{ - struct ast_private *ast = dev->dev_private; - struct ast_bo *astbo; - size_t acc_size; - int ret; - - astbo = kzalloc(sizeof(struct ast_bo), GFP_KERNEL); - if (!astbo) - return -ENOMEM; - - ret = drm_gem_object_init(dev, &astbo->gem, size); - if (ret) - goto error; - - astbo->bo.bdev = &ast->ttm.bdev; - - ast_ttm_placement(astbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); - - acc_size = ttm_bo_dma_acc_size(&ast->ttm.bdev, size, - sizeof(struct ast_bo)); - - ret = ttm_bo_init(&ast->ttm.bdev, &astbo->bo, size, - ttm_bo_type_device, &astbo->placement, - align >> PAGE_SHIFT, false, acc_size, - NULL, NULL, ast_bo_ttm_destroy); - if (ret) - goto error; - - *pastbo = astbo; - return 0; -error: - kfree(astbo); - return ret; -} - -static inline u64 ast_bo_gpu_offset(struct ast_bo *bo) -{ - return bo->bo.offset; -} - -int ast_bo_pin(struct ast_bo *bo, u32 pl_flag, u64 *gpu_addr) -{ - struct ttm_operation_ctx ctx = { false, false }; - int i, ret; - - if (bo->pin_count) { - bo->pin_count++; - if (gpu_addr) - *gpu_addr = ast_bo_gpu_offset(bo); - } - - ast_ttm_placement(bo, pl_flag); - for (i = 0; i < bo->placement.num_placement; i++) - bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT; - ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx); - if (ret) - return ret; - - bo->pin_count = 1; - if (gpu_addr) - *gpu_addr = ast_bo_gpu_offset(bo); - return 0; -} - -int ast_bo_unpin(struct ast_bo *bo) -{ - struct ttm_operation_ctx ctx = { false, false }; - int i; - if (!bo->pin_count) { - DRM_ERROR("unpin bad %p\n", bo); - return 0; - } - bo->pin_count--; - if (bo->pin_count) - return 0; - - for (i = 0; i < bo->placement.num_placement ; i++) - bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT; - return ttm_bo_validate(&bo->bo, &bo->placement, &ctx); -} - -int ast_bo_push_sysram(struct ast_bo *bo) -{ - struct ttm_operation_ctx ctx = { false, false }; - int i, ret; - if (!bo->pin_count) { - DRM_ERROR("unpin bad %p\n", bo); - return 0; - } - bo->pin_count--; - if (bo->pin_count) - return 0; - - if (bo->kmap.virtual) - ttm_bo_kunmap(&bo->kmap); - - ast_ttm_placement(bo, TTM_PL_FLAG_SYSTEM); - for (i = 0; i < bo->placement.num_placement ; i++) - bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT; - - ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx); - if (ret) { - DRM_ERROR("pushing to VRAM failed\n"); - return ret; - } - return 0; -} - -int ast_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct drm_file *file_priv = filp->private_data; - struct ast_private *ast = file_priv->minor->dev->dev_private; - - return ttm_bo_mmap(filp, vma, &ast->ttm.bdev); -} diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c index e836e2de35ce..fdd607ad27fe 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c @@ -603,8 +603,6 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p, const struct drm_display_mode *mode; struct drm_crtc_state *crtc_state; unsigned int tmp; - int hsub = 1; - int vsub = 1; int ret; int i; @@ -642,13 +640,10 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p, if (state->nplanes > ATMEL_HLCDC_LAYER_MAX_PLANES) return -EINVAL; - hsub = drm_format_horz_chroma_subsampling(fb->format->format); - vsub = drm_format_vert_chroma_subsampling(fb->format->format); - for (i = 0; i < state->nplanes; i++) { unsigned int offset = 0; - int xdiv = i ? hsub : 1; - int ydiv = i ? vsub : 1; + int xdiv = i ? fb->format->hsub : 1; + int ydiv = i ? fb->format->vsub : 1; state->bpp[i] = fb->format->cpp[i]; if (!state->bpp[i]) diff --git a/drivers/gpu/drm/bochs/Kconfig b/drivers/gpu/drm/bochs/Kconfig index 17885fab131d..32b043abb668 100644 --- a/drivers/gpu/drm/bochs/Kconfig +++ b/drivers/gpu/drm/bochs/Kconfig @@ -3,7 +3,7 @@ config DRM_BOCHS tristate "DRM Support for bochs dispi vga interface (qemu stdvga)" depends on DRM && PCI && MMU select DRM_KMS_HELPER - select DRM_TTM + select DRM_VRAM_HELPER help Choose this option for qemu. If M is selected the module will be called bochs-drm. diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h index 341cc9d1bab4..cc35d492142c 100644 --- a/drivers/gpu/drm/bochs/bochs.h +++ b/drivers/gpu/drm/bochs/bochs.h @@ -10,9 +10,9 @@ #include #include +#include -#include -#include +#include /* ---------------------------------------------------------------------- */ @@ -73,38 +73,8 @@ struct bochs_device { struct drm_device *dev; struct drm_simple_display_pipe pipe; struct drm_connector connector; - - /* ttm */ - struct { - struct ttm_bo_device bdev; - bool initialized; - } ttm; }; -struct bochs_bo { - struct ttm_buffer_object bo; - struct ttm_placement placement; - struct ttm_bo_kmap_obj kmap; - struct drm_gem_object gem; - struct ttm_place placements[3]; - int pin_count; -}; - -static inline struct bochs_bo *bochs_bo(struct ttm_buffer_object *bo) -{ - return container_of(bo, struct bochs_bo, bo); -} - -static inline struct bochs_bo *gem_to_bochs_bo(struct drm_gem_object *gem) -{ - return container_of(gem, struct bochs_bo, gem); -} - -static inline u64 bochs_bo_mmap_offset(struct bochs_bo *bo) -{ - return drm_vma_node_offset_addr(&bo->bo.vma_node); -} - /* ---------------------------------------------------------------------- */ /* bochs_hw.c */ @@ -122,26 +92,6 @@ int bochs_hw_load_edid(struct bochs_device *bochs); /* bochs_mm.c */ int bochs_mm_init(struct bochs_device *bochs); void bochs_mm_fini(struct bochs_device *bochs); -int bochs_mmap(struct file *filp, struct vm_area_struct *vma); - -int bochs_gem_create(struct drm_device *dev, u32 size, bool iskernel, - struct drm_gem_object **obj); -int bochs_gem_init_object(struct drm_gem_object *obj); -void bochs_gem_free_object(struct drm_gem_object *obj); -int bochs_dumb_create(struct drm_file *file, struct drm_device *dev, - struct drm_mode_create_dumb *args); -int bochs_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev, - uint32_t handle, uint64_t *offset); - -int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag); -int bochs_bo_unpin(struct bochs_bo *bo); - -int bochs_gem_prime_pin(struct drm_gem_object *obj); -void bochs_gem_prime_unpin(struct drm_gem_object *obj); -void *bochs_gem_prime_vmap(struct drm_gem_object *obj); -void bochs_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); -int bochs_gem_prime_mmap(struct drm_gem_object *obj, - struct vm_area_struct *vma); /* bochs_kms.c */ int bochs_kms_init(struct bochs_device *bochs); diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c index 6b6e037258c3..e7512a6564a3 100644 --- a/drivers/gpu/drm/bochs/bochs_drv.c +++ b/drivers/gpu/drm/bochs/bochs_drv.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "bochs.h" @@ -63,14 +64,7 @@ err: static const struct file_operations bochs_fops = { .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - .compat_ioctl = drm_compat_ioctl, - .poll = drm_poll, - .read = drm_read, - .llseek = no_llseek, - .mmap = bochs_mmap, + DRM_VRAM_MM_FILE_OPERATIONS }; static struct drm_driver bochs_driver = { @@ -82,17 +76,8 @@ static struct drm_driver bochs_driver = { .date = "20130925", .major = 1, .minor = 0, - .gem_free_object_unlocked = bochs_gem_free_object, - .dumb_create = bochs_dumb_create, - .dumb_map_offset = bochs_dumb_mmap_offset, - - .gem_prime_export = drm_gem_prime_export, - .gem_prime_import = drm_gem_prime_import, - .gem_prime_pin = bochs_gem_prime_pin, - .gem_prime_unpin = bochs_gem_prime_unpin, - .gem_prime_vmap = bochs_gem_prime_vmap, - .gem_prime_vunmap = bochs_gem_prime_vunmap, - .gem_prime_mmap = bochs_gem_prime_mmap, + DRM_GEM_VRAM_DRIVER, + DRM_GEM_VRAM_DRIVER_PRIME, }; /* ---------------------------------------------------------------------- */ @@ -174,6 +159,7 @@ static void bochs_pci_remove(struct pci_dev *pdev) { struct drm_device *dev = pci_get_drvdata(pdev); + drm_atomic_helper_shutdown(dev); drm_dev_unregister(dev); bochs_unload(dev); drm_dev_put(dev); diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index 5e905f50449d..9e3ee7b511fb 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -30,16 +30,16 @@ static const uint32_t bochs_formats[] = { static void bochs_plane_update(struct bochs_device *bochs, struct drm_plane_state *state) { - struct bochs_bo *bo; + struct drm_gem_vram_object *gbo; if (!state->fb || !bochs->stride) return; - bo = gem_to_bochs_bo(state->fb->obj[0]); + gbo = drm_gem_vram_of_gem(state->fb->obj[0]); bochs_hw_setbase(bochs, state->crtc_x, state->crtc_y, - bo->bo.offset); + gbo->bo.offset); bochs_hw_setformat(bochs, state->fb->format); } @@ -72,23 +72,23 @@ static void bochs_pipe_update(struct drm_simple_display_pipe *pipe, static int bochs_pipe_prepare_fb(struct drm_simple_display_pipe *pipe, struct drm_plane_state *new_state) { - struct bochs_bo *bo; + struct drm_gem_vram_object *gbo; if (!new_state->fb) return 0; - bo = gem_to_bochs_bo(new_state->fb->obj[0]); - return bochs_bo_pin(bo, TTM_PL_FLAG_VRAM); + gbo = drm_gem_vram_of_gem(new_state->fb->obj[0]); + return drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM); } static void bochs_pipe_cleanup_fb(struct drm_simple_display_pipe *pipe, struct drm_plane_state *old_state) { - struct bochs_bo *bo; + struct drm_gem_vram_object *gbo; if (!old_state->fb) return; - bo = gem_to_bochs_bo(old_state->fb->obj[0]); - bochs_bo_unpin(bo); + gbo = drm_gem_vram_of_gem(old_state->fb->obj[0]); + drm_gem_vram_unpin(gbo); } static const struct drm_simple_display_pipe_funcs bochs_pipe_funcs = { diff --git a/drivers/gpu/drm/bochs/bochs_mm.c b/drivers/gpu/drm/bochs/bochs_mm.c index 4a40308169c4..543499c07139 100644 --- a/drivers/gpu/drm/bochs/bochs_mm.c +++ b/drivers/gpu/drm/bochs/bochs_mm.c @@ -7,435 +7,22 @@ #include "bochs.h" -static void bochs_ttm_placement(struct bochs_bo *bo, int domain); - /* ---------------------------------------------------------------------- */ -static inline struct bochs_device *bochs_bdev(struct ttm_bo_device *bd) -{ - return container_of(bd, struct bochs_device, ttm.bdev); -} - -static void bochs_bo_ttm_destroy(struct ttm_buffer_object *tbo) -{ - struct bochs_bo *bo; - - bo = container_of(tbo, struct bochs_bo, bo); - drm_gem_object_release(&bo->gem); - kfree(bo); -} - -static bool bochs_ttm_bo_is_bochs_bo(struct ttm_buffer_object *bo) -{ - if (bo->destroy == &bochs_bo_ttm_destroy) - return true; - return false; -} - -static int bochs_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, - struct ttm_mem_type_manager *man) -{ - switch (type) { - case TTM_PL_SYSTEM: - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; - man->available_caching = TTM_PL_MASK_CACHING; - man->default_caching = TTM_PL_FLAG_CACHED; - break; - case TTM_PL_VRAM: - man->func = &ttm_bo_manager_func; - man->flags = TTM_MEMTYPE_FLAG_FIXED | - TTM_MEMTYPE_FLAG_MAPPABLE; - man->available_caching = TTM_PL_FLAG_UNCACHED | - TTM_PL_FLAG_WC; - man->default_caching = TTM_PL_FLAG_WC; - break; - default: - DRM_ERROR("Unsupported memory type %u\n", (unsigned)type); - return -EINVAL; - } - return 0; -} - -static void -bochs_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl) -{ - struct bochs_bo *bochsbo = bochs_bo(bo); - - if (!bochs_ttm_bo_is_bochs_bo(bo)) - return; - - bochs_ttm_placement(bochsbo, TTM_PL_FLAG_SYSTEM); - *pl = bochsbo->placement; -} - -static int bochs_bo_verify_access(struct ttm_buffer_object *bo, - struct file *filp) -{ - struct bochs_bo *bochsbo = bochs_bo(bo); - - return drm_vma_node_verify_access(&bochsbo->gem.vma_node, - filp->private_data); -} - -static int bochs_ttm_io_mem_reserve(struct ttm_bo_device *bdev, - struct ttm_mem_reg *mem) -{ - struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; - struct bochs_device *bochs = bochs_bdev(bdev); - - mem->bus.addr = NULL; - mem->bus.offset = 0; - mem->bus.size = mem->num_pages << PAGE_SHIFT; - mem->bus.base = 0; - mem->bus.is_iomem = false; - if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE)) - return -EINVAL; - switch (mem->mem_type) { - case TTM_PL_SYSTEM: - /* system memory */ - return 0; - case TTM_PL_VRAM: - mem->bus.offset = mem->start << PAGE_SHIFT; - mem->bus.base = bochs->fb_base; - mem->bus.is_iomem = true; - break; - default: - return -EINVAL; - break; - } - return 0; -} - -static void bochs_ttm_io_mem_free(struct ttm_bo_device *bdev, - struct ttm_mem_reg *mem) -{ -} - -static void bochs_ttm_backend_destroy(struct ttm_tt *tt) -{ - ttm_tt_fini(tt); - kfree(tt); -} - -static struct ttm_backend_func bochs_tt_backend_func = { - .destroy = &bochs_ttm_backend_destroy, -}; - -static struct ttm_tt *bochs_ttm_tt_create(struct ttm_buffer_object *bo, - uint32_t page_flags) -{ - struct ttm_tt *tt; - - tt = kzalloc(sizeof(struct ttm_tt), GFP_KERNEL); - if (tt == NULL) - return NULL; - tt->func = &bochs_tt_backend_func; - if (ttm_tt_init(tt, bo, page_flags)) { - kfree(tt); - return NULL; - } - return tt; -} - -static struct ttm_bo_driver bochs_bo_driver = { - .ttm_tt_create = bochs_ttm_tt_create, - .init_mem_type = bochs_bo_init_mem_type, - .eviction_valuable = ttm_bo_eviction_valuable, - .evict_flags = bochs_bo_evict_flags, - .move = NULL, - .verify_access = bochs_bo_verify_access, - .io_mem_reserve = &bochs_ttm_io_mem_reserve, - .io_mem_free = &bochs_ttm_io_mem_free, -}; - int bochs_mm_init(struct bochs_device *bochs) { - struct ttm_bo_device *bdev = &bochs->ttm.bdev; - int ret; + struct drm_vram_mm *vmm; - ret = ttm_bo_device_init(&bochs->ttm.bdev, - &bochs_bo_driver, - bochs->dev->anon_inode->i_mapping, - true); - if (ret) { - DRM_ERROR("Error initialising bo driver; %d\n", ret); - return ret; - } - - ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM, - bochs->fb_size >> PAGE_SHIFT); - if (ret) { - DRM_ERROR("Failed ttm VRAM init: %d\n", ret); - return ret; - } - - bochs->ttm.initialized = true; - return 0; + vmm = drm_vram_helper_alloc_mm(bochs->dev, bochs->fb_base, + bochs->fb_size, + &drm_gem_vram_mm_funcs); + return PTR_ERR_OR_ZERO(vmm); } void bochs_mm_fini(struct bochs_device *bochs) { - if (!bochs->ttm.initialized) + if (!bochs->dev->vram_mm) return; - ttm_bo_device_release(&bochs->ttm.bdev); - bochs->ttm.initialized = false; -} - -static void bochs_ttm_placement(struct bochs_bo *bo, int domain) -{ - unsigned i; - u32 c = 0; - bo->placement.placement = bo->placements; - bo->placement.busy_placement = bo->placements; - if (domain & TTM_PL_FLAG_VRAM) { - bo->placements[c++].flags = TTM_PL_FLAG_WC - | TTM_PL_FLAG_UNCACHED - | TTM_PL_FLAG_VRAM; - } - if (domain & TTM_PL_FLAG_SYSTEM) { - bo->placements[c++].flags = TTM_PL_MASK_CACHING - | TTM_PL_FLAG_SYSTEM; - } - if (!c) { - bo->placements[c++].flags = TTM_PL_MASK_CACHING - | TTM_PL_FLAG_SYSTEM; - } - for (i = 0; i < c; ++i) { - bo->placements[i].fpfn = 0; - bo->placements[i].lpfn = 0; - } - bo->placement.num_placement = c; - bo->placement.num_busy_placement = c; -} - -int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag) -{ - struct ttm_operation_ctx ctx = { false, false }; - int i, ret; - - if (bo->pin_count) { - bo->pin_count++; - return 0; - } - - bochs_ttm_placement(bo, pl_flag); - for (i = 0; i < bo->placement.num_placement; i++) - bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT; - ret = ttm_bo_reserve(&bo->bo, true, false, NULL); - if (ret) - return ret; - ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx); - ttm_bo_unreserve(&bo->bo); - if (ret) - return ret; - - bo->pin_count = 1; - return 0; -} - -int bochs_bo_unpin(struct bochs_bo *bo) -{ - struct ttm_operation_ctx ctx = { false, false }; - int i, ret; - - if (!bo->pin_count) { - DRM_ERROR("unpin bad %p\n", bo); - return 0; - } - bo->pin_count--; - - if (bo->pin_count) - return 0; - - for (i = 0; i < bo->placement.num_placement; i++) - bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT; - ret = ttm_bo_reserve(&bo->bo, true, false, NULL); - if (ret) - return ret; - ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx); - ttm_bo_unreserve(&bo->bo); - if (ret) - return ret; - - return 0; -} - -int bochs_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct drm_file *file_priv = filp->private_data; - struct bochs_device *bochs = file_priv->minor->dev->dev_private; - - return ttm_bo_mmap(filp, vma, &bochs->ttm.bdev); -} - -/* ---------------------------------------------------------------------- */ - -static int bochs_bo_create(struct drm_device *dev, int size, int align, - uint32_t flags, struct bochs_bo **pbochsbo) -{ - struct bochs_device *bochs = dev->dev_private; - struct bochs_bo *bochsbo; - size_t acc_size; - int ret; - - bochsbo = kzalloc(sizeof(struct bochs_bo), GFP_KERNEL); - if (!bochsbo) - return -ENOMEM; - - ret = drm_gem_object_init(dev, &bochsbo->gem, size); - if (ret) { - kfree(bochsbo); - return ret; - } - - bochsbo->bo.bdev = &bochs->ttm.bdev; - bochsbo->bo.bdev->dev_mapping = dev->anon_inode->i_mapping; - - bochs_ttm_placement(bochsbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); - - acc_size = ttm_bo_dma_acc_size(&bochs->ttm.bdev, size, - sizeof(struct bochs_bo)); - - ret = ttm_bo_init(&bochs->ttm.bdev, &bochsbo->bo, size, - ttm_bo_type_device, &bochsbo->placement, - align >> PAGE_SHIFT, false, acc_size, - NULL, NULL, bochs_bo_ttm_destroy); - if (ret) - return ret; - - *pbochsbo = bochsbo; - return 0; -} - -int bochs_gem_create(struct drm_device *dev, u32 size, bool iskernel, - struct drm_gem_object **obj) -{ - struct bochs_bo *bochsbo; - int ret; - - *obj = NULL; - - size = PAGE_ALIGN(size); - if (size == 0) - return -EINVAL; - - ret = bochs_bo_create(dev, size, 0, 0, &bochsbo); - if (ret) { - if (ret != -ERESTARTSYS) - DRM_ERROR("failed to allocate GEM object\n"); - return ret; - } - *obj = &bochsbo->gem; - return 0; -} - -int bochs_dumb_create(struct drm_file *file, struct drm_device *dev, - struct drm_mode_create_dumb *args) -{ - struct drm_gem_object *gobj; - u32 handle; - int ret; - - args->pitch = args->width * ((args->bpp + 7) / 8); - args->size = args->pitch * args->height; - - ret = bochs_gem_create(dev, args->size, false, - &gobj); - if (ret) - return ret; - - ret = drm_gem_handle_create(file, gobj, &handle); - drm_gem_object_put_unlocked(gobj); - if (ret) - return ret; - - args->handle = handle; - return 0; -} - -static void bochs_bo_unref(struct bochs_bo **bo) -{ - struct ttm_buffer_object *tbo; - - if ((*bo) == NULL) - return; - - tbo = &((*bo)->bo); - ttm_bo_put(tbo); - *bo = NULL; -} - -void bochs_gem_free_object(struct drm_gem_object *obj) -{ - struct bochs_bo *bochs_bo = gem_to_bochs_bo(obj); - - bochs_bo_unref(&bochs_bo); -} - -int bochs_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev, - uint32_t handle, uint64_t *offset) -{ - struct drm_gem_object *obj; - struct bochs_bo *bo; - - obj = drm_gem_object_lookup(file, handle); - if (obj == NULL) - return -ENOENT; - - bo = gem_to_bochs_bo(obj); - *offset = bochs_bo_mmap_offset(bo); - - drm_gem_object_put_unlocked(obj); - return 0; -} - -/* ---------------------------------------------------------------------- */ - -int bochs_gem_prime_pin(struct drm_gem_object *obj) -{ - struct bochs_bo *bo = gem_to_bochs_bo(obj); - - return bochs_bo_pin(bo, TTM_PL_FLAG_VRAM); -} - -void bochs_gem_prime_unpin(struct drm_gem_object *obj) -{ - struct bochs_bo *bo = gem_to_bochs_bo(obj); - - bochs_bo_unpin(bo); -} - -void *bochs_gem_prime_vmap(struct drm_gem_object *obj) -{ - struct bochs_bo *bo = gem_to_bochs_bo(obj); - bool is_iomem; - int ret; - - ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM); - if (ret) - return NULL; - ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); - if (ret) { - bochs_bo_unpin(bo); - return NULL; - } - return ttm_kmap_obj_virtual(&bo->kmap, &is_iomem); -} - -void bochs_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) -{ - struct bochs_bo *bo = gem_to_bochs_bo(obj); - - ttm_bo_kunmap(&bo->kmap); - bochs_bo_unpin(bo); -} - -int bochs_gem_prime_mmap(struct drm_gem_object *obj, - struct vm_area_struct *vma) -{ - struct bochs_bo *bo = gem_to_bochs_bo(obj); - - bo->gem.vma_node.vm_node.start = bo->bo.vma_node.vm_node.start; - return drm_gem_prime_mmap(obj, vma); + drm_vram_helper_release_mm(bochs->dev); } diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c index 38eeaf8ba959..000ba7ce1ba8 100644 --- a/drivers/gpu/drm/bridge/panel.c +++ b/drivers/gpu/drm/bridge/panel.c @@ -9,13 +9,12 @@ */ #include -#include #include #include #include #include -#include #include +#include struct panel_bridge { struct drm_bridge bridge; diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h deleted file mode 100644 index 1bd816be3aae..000000000000 --- a/drivers/gpu/drm/cirrus/cirrus_drv.h +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2012 Red Hat - * - * This file is subject to the terms and conditions of the GNU General - * Public License version 2. See the file COPYING in the main - * directory of this archive for more details. - * - * Authors: Matthew Garrett - * Dave Airlie - */ -#ifndef __CIRRUS_DRV_H__ -#define __CIRRUS_DRV_H__ - -#include