Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: add generic display panic helper code

Pull this out of Jocelyn's patch and make it generic.

Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: Lu Yao <yaolu@kylinos.cn>
Cc: Jocelyn Falempe <jfalempe@redhat.com>
Cc: Harry Wentland <harry.wentland@amd.com>

+85
+80
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
··· 33 33 #include "soc15_common.h" 34 34 #include "gc/gc_11_0_0_offset.h" 35 35 #include "gc/gc_11_0_0_sh_mask.h" 36 + #include "bif/bif_4_1_d.h" 36 37 #include <asm/div64.h> 37 38 38 39 #include <linux/pci.h> ··· 1789 1788 return 0; 1790 1789 } 1791 1790 1791 + /* panic_bo is set in amdgpu_dm_plane_get_scanout_buffer() and only used in amdgpu_dm_set_pixel() 1792 + * they are called from the panic handler, and protected by the drm_panic spinlock. 1793 + */ 1794 + static struct amdgpu_bo *panic_abo; 1795 + 1796 + /* Use the indirect MMIO to write each pixel to the GPU VRAM, 1797 + * This is a simplified version of amdgpu_device_mm_access() 1798 + */ 1799 + static void amdgpu_display_set_pixel(struct drm_scanout_buffer *sb, 1800 + unsigned int x, 1801 + unsigned int y, 1802 + u32 color) 1803 + { 1804 + struct amdgpu_res_cursor cursor; 1805 + unsigned long offset; 1806 + struct amdgpu_bo *abo = panic_abo; 1807 + struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev); 1808 + uint32_t tmp; 1809 + 1810 + offset = x * 4 + y * sb->pitch[0]; 1811 + amdgpu_res_first(abo->tbo.resource, offset, 4, &cursor); 1812 + 1813 + tmp = cursor.start >> 31; 1814 + WREG32_NO_KIQ(mmMM_INDEX, ((uint32_t) cursor.start) | 0x80000000); 1815 + if (tmp != 0xffffffff) 1816 + WREG32_NO_KIQ(mmMM_INDEX_HI, tmp); 1817 + WREG32_NO_KIQ(mmMM_DATA, color); 1818 + } 1819 + 1820 + int amdgpu_display_get_scanout_buffer(struct drm_plane *plane, 1821 + struct drm_scanout_buffer *sb) 1822 + { 1823 + struct amdgpu_bo *abo; 1824 + struct drm_framebuffer *fb = plane->state->fb; 1825 + 1826 + if (!fb) 1827 + return -EINVAL; 1828 + 1829 + DRM_DEBUG_KMS("Framebuffer %dx%d %p4cc\n", fb->width, fb->height, &fb->format->format); 1830 + 1831 + abo = gem_to_amdgpu_bo(fb->obj[0]); 1832 + if (!abo) 1833 + return -EINVAL; 1834 + 1835 + sb->width = fb->width; 1836 + sb->height = fb->height; 1837 + /* Use the generic linear format, because tiling will be disabled in panic_flush() */ 1838 + sb->format = drm_format_info(fb->format->format); 1839 + if (!sb->format) 1840 + return -EINVAL; 1841 + 1842 + sb->pitch[0] = fb->pitches[0]; 1843 + 1844 + if (abo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) { 1845 + if (abo->tbo.resource->mem_type != TTM_PL_VRAM) { 1846 + drm_warn(plane->dev, "amdgpu panic, framebuffer not in VRAM\n"); 1847 + return -EINVAL; 1848 + } 1849 + /* Only handle 32bits format, to simplify mmio access */ 1850 + if (fb->format->cpp[0] != 4) { 1851 + drm_warn(plane->dev, "amdgpu panic, pixel format is not 32bits\n"); 1852 + return -EINVAL; 1853 + } 1854 + sb->set_pixel = amdgpu_display_set_pixel; 1855 + panic_abo = abo; 1856 + return 0; 1857 + } 1858 + if (!abo->kmap.virtual && 1859 + ttm_bo_kmap(&abo->tbo, 0, PFN_UP(abo->tbo.base.size), &abo->kmap)) { 1860 + drm_warn(plane->dev, "amdgpu bo map failed, panic won't be displayed\n"); 1861 + return -ENOMEM; 1862 + } 1863 + if (abo->kmap.bo_kmap_type & TTM_BO_MAP_IOMEM_MASK) 1864 + iosys_map_set_vaddr_iomem(&sb->map[0], abo->kmap.virtual); 1865 + else 1866 + iosys_map_set_vaddr(&sb->map[0], abo->kmap.virtual); 1867 + 1868 + return 0; 1869 + }
+5
drivers/gpu/drm/amd/amdgpu/amdgpu_display.h
··· 23 23 #ifndef __AMDGPU_DISPLAY_H__ 24 24 #define __AMDGPU_DISPLAY_H__ 25 25 26 + #include <drm/drm_panic.h> 27 + 26 28 #define amdgpu_display_vblank_get_counter(adev, crtc) (adev)->mode_info.funcs->vblank_get_counter((adev), (crtc)) 27 29 #define amdgpu_display_backlight_set_level(adev, e, l) (adev)->mode_info.funcs->backlight_set_level((e), (l)) 28 30 #define amdgpu_display_backlight_get_level(adev, e) (adev)->mode_info.funcs->backlight_get_level((e)) ··· 50 48 51 49 int amdgpu_display_suspend_helper(struct amdgpu_device *adev); 52 50 int amdgpu_display_resume_helper(struct amdgpu_device *adev); 51 + 52 + int amdgpu_display_get_scanout_buffer(struct drm_plane *plane, 53 + struct drm_scanout_buffer *sb); 53 54 54 55 #endif