···31313232#include "r600_blit_shaders.h"33333434+/* 23 bits of float fractional data */3535+#define I2F_FRAC_BITS 233636+#define I2F_MASK ((1 << I2F_FRAC_BITS) - 1)3737+3838+/*3939+ * Converts unsigned integer into 32-bit IEEE floating point representation.4040+ * Will be exact from 0 to 2^24. Above that, we round towards zero4141+ * as the fractional bits will not fit in a float. (It would be better to4242+ * round towards even as the fpu does, but that is slower.)4343+ */4444+static __pure uint32_t int2float(uint32_t x)4545+{4646+ uint32_t msb, exponent, fraction;4747+4848+ /* Zero is special */4949+ if (!x) return 0;5050+5151+ /* Get location of the most significant bit */5252+ msb = __fls(x);5353+5454+ /*5555+ * Use a rotate instead of a shift because that works both leftwards5656+ * and rightwards due to the mod(32) behaviour. This means we don't5757+ * need to check to see if we are above 2^24 or not.5858+ */5959+ fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;6060+ exponent = (127 + msb) << I2F_FRAC_BITS;6161+6262+ return fraction + exponent;6363+}6464+3465#define DI_PT_RECTLIST 0x113566#define DI_INDEX_SIZE_16_BIT 0x03667#define DI_SRC_SEL_AUTO_INDEX 0x2
-785
drivers/gpu/drm/radeon/r600_blit_kms.c
···11-/*22- * Copyright 2009 Advanced Micro Devices, Inc.33- * Copyright 2009 Red Hat Inc.44- *55- * Permission is hereby granted, free of charge, to any person obtaining a66- * copy of this software and associated documentation files (the "Software"),77- * to deal in the Software without restriction, including without limitation88- * the rights to use, copy, modify, merge, publish, distribute, sublicense,99- * and/or sell copies of the Software, and to permit persons to whom the1010- * Software is furnished to do so, subject to the following conditions:1111- *1212- * The above copyright notice and this permission notice (including the next1313- * paragraph) shall be included in all copies or substantial portions of the1414- * Software.1515- *1616- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR1717- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,1818- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL1919- * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR2020- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,2121- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER2222- * DEALINGS IN THE SOFTWARE.2323- *2424- */2525-2626-#include <drm/drmP.h>2727-#include <drm/radeon_drm.h>2828-#include "radeon.h"2929-3030-#include "r600d.h"3131-#include "r600_blit_shaders.h"3232-#include "radeon_blit_common.h"3333-3434-/* 23 bits of float fractional data */3535-#define I2F_FRAC_BITS 233636-#define I2F_MASK ((1 << I2F_FRAC_BITS) - 1)3737-3838-/*3939- * Converts unsigned integer into 32-bit IEEE floating point representation.4040- * Will be exact from 0 to 2^24. Above that, we round towards zero4141- * as the fractional bits will not fit in a float. (It would be better to4242- * round towards even as the fpu does, but that is slower.)4343- */4444-__pure uint32_t int2float(uint32_t x)4545-{4646- uint32_t msb, exponent, fraction;4747-4848- /* Zero is special */4949- if (!x) return 0;5050-5151- /* Get location of the most significant bit */5252- msb = __fls(x);5353-5454- /*5555- * Use a rotate instead of a shift because that works both leftwards5656- * and rightwards due to the mod(32) behaviour. This means we don't5757- * need to check to see if we are above 2^24 or not.5858- */5959- fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;6060- exponent = (127 + msb) << I2F_FRAC_BITS;6161-6262- return fraction + exponent;6363-}6464-6565-/* emits 21 on rv770+, 23 on r600 */6666-static void6767-set_render_target(struct radeon_device *rdev, int format,6868- int w, int h, u64 gpu_addr)6969-{7070- struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];7171- u32 cb_color_info;7272- int pitch, slice;7373-7474- h = ALIGN(h, 8);7575- if (h < 8)7676- h = 8;7777-7878- cb_color_info = CB_FORMAT(format) |7979- CB_SOURCE_FORMAT(CB_SF_EXPORT_NORM) |8080- CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);8181- pitch = (w / 8) - 1;8282- slice = ((w * h) / 64) - 1;8383-8484- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1));8585- radeon_ring_write(ring, (CB_COLOR0_BASE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);8686- radeon_ring_write(ring, gpu_addr >> 8);8787-8888- if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770) {8989- radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_BASE_UPDATE, 0));9090- radeon_ring_write(ring, 2 << 0);9191- }9292-9393- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1));9494- radeon_ring_write(ring, (CB_COLOR0_SIZE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);9595- radeon_ring_write(ring, (pitch << 0) | (slice << 10));9696-9797- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1));9898- radeon_ring_write(ring, (CB_COLOR0_VIEW - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);9999- radeon_ring_write(ring, 0);100100-101101- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1));102102- radeon_ring_write(ring, (CB_COLOR0_INFO - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);103103- radeon_ring_write(ring, cb_color_info);104104-105105- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1));106106- radeon_ring_write(ring, (CB_COLOR0_TILE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);107107- radeon_ring_write(ring, 0);108108-109109- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1));110110- radeon_ring_write(ring, (CB_COLOR0_FRAG - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);111111- radeon_ring_write(ring, 0);112112-113113- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1));114114- radeon_ring_write(ring, (CB_COLOR0_MASK - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);115115- radeon_ring_write(ring, 0);116116-}117117-118118-/* emits 5dw */119119-static void120120-cp_set_surface_sync(struct radeon_device *rdev,121121- u32 sync_type, u32 size,122122- u64 mc_addr)123123-{124124- struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];125125- u32 cp_coher_size;126126-127127- if (size == 0xffffffff)128128- cp_coher_size = 0xffffffff;129129- else130130- cp_coher_size = ((size + 255) >> 8);131131-132132- radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));133133- radeon_ring_write(ring, sync_type);134134- radeon_ring_write(ring, cp_coher_size);135135- radeon_ring_write(ring, mc_addr >> 8);136136- radeon_ring_write(ring, 10); /* poll interval */137137-}138138-139139-/* emits 21dw + 1 surface sync = 26dw */140140-static void141141-set_shaders(struct radeon_device *rdev)142142-{143143- struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];144144- u64 gpu_addr;145145- u32 sq_pgm_resources;146146-147147- /* setup shader regs */148148- sq_pgm_resources = (1 << 0);149149-150150- /* VS */151151- gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset;152152- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1));153153- radeon_ring_write(ring, (SQ_PGM_START_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);154154- radeon_ring_write(ring, gpu_addr >> 8);155155-156156- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1));157157- radeon_ring_write(ring, (SQ_PGM_RESOURCES_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);158158- radeon_ring_write(ring, sq_pgm_resources);159159-160160- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1));161161- radeon_ring_write(ring, (SQ_PGM_CF_OFFSET_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);162162- radeon_ring_write(ring, 0);163163-164164- /* PS */165165- gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.ps_offset;166166- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1));167167- radeon_ring_write(ring, (SQ_PGM_START_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);168168- radeon_ring_write(ring, gpu_addr >> 8);169169-170170- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1));171171- radeon_ring_write(ring, (SQ_PGM_RESOURCES_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);172172- radeon_ring_write(ring, sq_pgm_resources | (1 << 28));173173-174174- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1));175175- radeon_ring_write(ring, (SQ_PGM_EXPORTS_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);176176- radeon_ring_write(ring, 2);177177-178178- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1));179179- radeon_ring_write(ring, (SQ_PGM_CF_OFFSET_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);180180- radeon_ring_write(ring, 0);181181-182182- gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset;183183- cp_set_surface_sync(rdev, PACKET3_SH_ACTION_ENA, 512, gpu_addr);184184-}185185-186186-/* emits 9 + 1 sync (5) = 14*/187187-static void188188-set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr)189189-{190190- struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];191191- u32 sq_vtx_constant_word2;192192-193193- sq_vtx_constant_word2 = SQ_VTXC_BASE_ADDR_HI(upper_32_bits(gpu_addr) & 0xff) |194194- SQ_VTXC_STRIDE(16);195195-#ifdef __BIG_ENDIAN196196- sq_vtx_constant_word2 |= SQ_VTXC_ENDIAN_SWAP(SQ_ENDIAN_8IN32);197197-#endif198198-199199- radeon_ring_write(ring, PACKET3(PACKET3_SET_RESOURCE, 7));200200- radeon_ring_write(ring, 0x460);201201- radeon_ring_write(ring, gpu_addr & 0xffffffff);202202- radeon_ring_write(ring, 48 - 1);203203- radeon_ring_write(ring, sq_vtx_constant_word2);204204- radeon_ring_write(ring, 1 << 0);205205- radeon_ring_write(ring, 0);206206- radeon_ring_write(ring, 0);207207- radeon_ring_write(ring, SQ_TEX_VTX_VALID_BUFFER << 30);208208-209209- if ((rdev->family == CHIP_RV610) ||210210- (rdev->family == CHIP_RV620) ||211211- (rdev->family == CHIP_RS780) ||212212- (rdev->family == CHIP_RS880) ||213213- (rdev->family == CHIP_RV710))214214- cp_set_surface_sync(rdev,215215- PACKET3_TC_ACTION_ENA, 48, gpu_addr);216216- else217217- cp_set_surface_sync(rdev,218218- PACKET3_VC_ACTION_ENA, 48, gpu_addr);219219-}220220-221221-/* emits 9 */222222-static void223223-set_tex_resource(struct radeon_device *rdev,224224- int format, int w, int h, int pitch,225225- u64 gpu_addr, u32 size)226226-{227227- struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];228228- uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4;229229-230230- if (h < 1)231231- h = 1;232232-233233- sq_tex_resource_word0 = S_038000_DIM(V_038000_SQ_TEX_DIM_2D) |234234- S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);235235- sq_tex_resource_word0 |= S_038000_PITCH((pitch >> 3) - 1) |236236- S_038000_TEX_WIDTH(w - 1);237237-238238- sq_tex_resource_word1 = S_038004_DATA_FORMAT(format);239239- sq_tex_resource_word1 |= S_038004_TEX_HEIGHT(h - 1);240240-241241- sq_tex_resource_word4 = S_038010_REQUEST_SIZE(1) |242242- S_038010_DST_SEL_X(SQ_SEL_X) |243243- S_038010_DST_SEL_Y(SQ_SEL_Y) |244244- S_038010_DST_SEL_Z(SQ_SEL_Z) |245245- S_038010_DST_SEL_W(SQ_SEL_W);246246-247247- cp_set_surface_sync(rdev,248248- PACKET3_TC_ACTION_ENA, size, gpu_addr);249249-250250- radeon_ring_write(ring, PACKET3(PACKET3_SET_RESOURCE, 7));251251- radeon_ring_write(ring, 0);252252- radeon_ring_write(ring, sq_tex_resource_word0);253253- radeon_ring_write(ring, sq_tex_resource_word1);254254- radeon_ring_write(ring, gpu_addr >> 8);255255- radeon_ring_write(ring, gpu_addr >> 8);256256- radeon_ring_write(ring, sq_tex_resource_word4);257257- radeon_ring_write(ring, 0);258258- radeon_ring_write(ring, SQ_TEX_VTX_VALID_TEXTURE << 30);259259-}260260-261261-/* emits 12 */262262-static void263263-set_scissors(struct radeon_device *rdev, int x1, int y1,264264- int x2, int y2)265265-{266266- struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];267267- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2));268268- radeon_ring_write(ring, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);269269- radeon_ring_write(ring, (x1 << 0) | (y1 << 16));270270- radeon_ring_write(ring, (x2 << 0) | (y2 << 16));271271-272272- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2));273273- radeon_ring_write(ring, (PA_SC_GENERIC_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);274274- radeon_ring_write(ring, (x1 << 0) | (y1 << 16) | (1 << 31));275275- radeon_ring_write(ring, (x2 << 0) | (y2 << 16));276276-277277- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2));278278- radeon_ring_write(ring, (PA_SC_WINDOW_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);279279- radeon_ring_write(ring, (x1 << 0) | (y1 << 16) | (1 << 31));280280- radeon_ring_write(ring, (x2 << 0) | (y2 << 16));281281-}282282-283283-/* emits 10 */284284-static void285285-draw_auto(struct radeon_device *rdev)286286-{287287- struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];288288- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));289289- radeon_ring_write(ring, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);290290- radeon_ring_write(ring, DI_PT_RECTLIST);291291-292292- radeon_ring_write(ring, PACKET3(PACKET3_INDEX_TYPE, 0));293293- radeon_ring_write(ring,294294-#ifdef __BIG_ENDIAN295295- (2 << 2) |296296-#endif297297- DI_INDEX_SIZE_16_BIT);298298-299299- radeon_ring_write(ring, PACKET3(PACKET3_NUM_INSTANCES, 0));300300- radeon_ring_write(ring, 1);301301-302302- radeon_ring_write(ring, PACKET3(PACKET3_DRAW_INDEX_AUTO, 1));303303- radeon_ring_write(ring, 3);304304- radeon_ring_write(ring, DI_SRC_SEL_AUTO_INDEX);305305-306306-}307307-308308-/* emits 14 */309309-static void310310-set_default_state(struct radeon_device *rdev)311311-{312312- struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];313313- u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2;314314- u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2;315315- int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs;316316- int num_ps_threads, num_vs_threads, num_gs_threads, num_es_threads;317317- int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries;318318- u64 gpu_addr;319319- int dwords;320320-321321- switch (rdev->family) {322322- case CHIP_R600:323323- num_ps_gprs = 192;324324- num_vs_gprs = 56;325325- num_temp_gprs = 4;326326- num_gs_gprs = 0;327327- num_es_gprs = 0;328328- num_ps_threads = 136;329329- num_vs_threads = 48;330330- num_gs_threads = 4;331331- num_es_threads = 4;332332- num_ps_stack_entries = 128;333333- num_vs_stack_entries = 128;334334- num_gs_stack_entries = 0;335335- num_es_stack_entries = 0;336336- break;337337- case CHIP_RV630:338338- case CHIP_RV635:339339- num_ps_gprs = 84;340340- num_vs_gprs = 36;341341- num_temp_gprs = 4;342342- num_gs_gprs = 0;343343- num_es_gprs = 0;344344- num_ps_threads = 144;345345- num_vs_threads = 40;346346- num_gs_threads = 4;347347- num_es_threads = 4;348348- num_ps_stack_entries = 40;349349- num_vs_stack_entries = 40;350350- num_gs_stack_entries = 32;351351- num_es_stack_entries = 16;352352- break;353353- case CHIP_RV610:354354- case CHIP_RV620:355355- case CHIP_RS780:356356- case CHIP_RS880:357357- default:358358- num_ps_gprs = 84;359359- num_vs_gprs = 36;360360- num_temp_gprs = 4;361361- num_gs_gprs = 0;362362- num_es_gprs = 0;363363- num_ps_threads = 136;364364- num_vs_threads = 48;365365- num_gs_threads = 4;366366- num_es_threads = 4;367367- num_ps_stack_entries = 40;368368- num_vs_stack_entries = 40;369369- num_gs_stack_entries = 32;370370- num_es_stack_entries = 16;371371- break;372372- case CHIP_RV670:373373- num_ps_gprs = 144;374374- num_vs_gprs = 40;375375- num_temp_gprs = 4;376376- num_gs_gprs = 0;377377- num_es_gprs = 0;378378- num_ps_threads = 136;379379- num_vs_threads = 48;380380- num_gs_threads = 4;381381- num_es_threads = 4;382382- num_ps_stack_entries = 40;383383- num_vs_stack_entries = 40;384384- num_gs_stack_entries = 32;385385- num_es_stack_entries = 16;386386- break;387387- case CHIP_RV770:388388- num_ps_gprs = 192;389389- num_vs_gprs = 56;390390- num_temp_gprs = 4;391391- num_gs_gprs = 0;392392- num_es_gprs = 0;393393- num_ps_threads = 188;394394- num_vs_threads = 60;395395- num_gs_threads = 0;396396- num_es_threads = 0;397397- num_ps_stack_entries = 256;398398- num_vs_stack_entries = 256;399399- num_gs_stack_entries = 0;400400- num_es_stack_entries = 0;401401- break;402402- case CHIP_RV730:403403- case CHIP_RV740:404404- num_ps_gprs = 84;405405- num_vs_gprs = 36;406406- num_temp_gprs = 4;407407- num_gs_gprs = 0;408408- num_es_gprs = 0;409409- num_ps_threads = 188;410410- num_vs_threads = 60;411411- num_gs_threads = 0;412412- num_es_threads = 0;413413- num_ps_stack_entries = 128;414414- num_vs_stack_entries = 128;415415- num_gs_stack_entries = 0;416416- num_es_stack_entries = 0;417417- break;418418- case CHIP_RV710:419419- num_ps_gprs = 192;420420- num_vs_gprs = 56;421421- num_temp_gprs = 4;422422- num_gs_gprs = 0;423423- num_es_gprs = 0;424424- num_ps_threads = 144;425425- num_vs_threads = 48;426426- num_gs_threads = 0;427427- num_es_threads = 0;428428- num_ps_stack_entries = 128;429429- num_vs_stack_entries = 128;430430- num_gs_stack_entries = 0;431431- num_es_stack_entries = 0;432432- break;433433- }434434-435435- if ((rdev->family == CHIP_RV610) ||436436- (rdev->family == CHIP_RV620) ||437437- (rdev->family == CHIP_RS780) ||438438- (rdev->family == CHIP_RS880) ||439439- (rdev->family == CHIP_RV710))440440- sq_config = 0;441441- else442442- sq_config = VC_ENABLE;443443-444444- sq_config |= (DX9_CONSTS |445445- ALU_INST_PREFER_VECTOR |446446- PS_PRIO(0) |447447- VS_PRIO(1) |448448- GS_PRIO(2) |449449- ES_PRIO(3));450450-451451- sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(num_ps_gprs) |452452- NUM_VS_GPRS(num_vs_gprs) |453453- NUM_CLAUSE_TEMP_GPRS(num_temp_gprs));454454- sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(num_gs_gprs) |455455- NUM_ES_GPRS(num_es_gprs));456456- sq_thread_resource_mgmt = (NUM_PS_THREADS(num_ps_threads) |457457- NUM_VS_THREADS(num_vs_threads) |458458- NUM_GS_THREADS(num_gs_threads) |459459- NUM_ES_THREADS(num_es_threads));460460- sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(num_ps_stack_entries) |461461- NUM_VS_STACK_ENTRIES(num_vs_stack_entries));462462- sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(num_gs_stack_entries) |463463- NUM_ES_STACK_ENTRIES(num_es_stack_entries));464464-465465- /* emit an IB pointing at default state */466466- dwords = ALIGN(rdev->r600_blit.state_len, 0x10);467467- gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset;468468- radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));469469- radeon_ring_write(ring,470470-#ifdef __BIG_ENDIAN471471- (2 << 0) |472472-#endif473473- (gpu_addr & 0xFFFFFFFC));474474- radeon_ring_write(ring, upper_32_bits(gpu_addr) & 0xFF);475475- radeon_ring_write(ring, dwords);476476-477477- /* SQ config */478478- radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 6));479479- radeon_ring_write(ring, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);480480- radeon_ring_write(ring, sq_config);481481- radeon_ring_write(ring, sq_gpr_resource_mgmt_1);482482- radeon_ring_write(ring, sq_gpr_resource_mgmt_2);483483- radeon_ring_write(ring, sq_thread_resource_mgmt);484484- radeon_ring_write(ring, sq_stack_resource_mgmt_1);485485- radeon_ring_write(ring, sq_stack_resource_mgmt_2);486486-}487487-488488-int r600_blit_init(struct radeon_device *rdev)489489-{490490- u32 obj_size;491491- int i, r, dwords;492492- void *ptr;493493- u32 packet2s[16];494494- int num_packet2s = 0;495495-496496- rdev->r600_blit.primitives.set_render_target = set_render_target;497497- rdev->r600_blit.primitives.cp_set_surface_sync = cp_set_surface_sync;498498- rdev->r600_blit.primitives.set_shaders = set_shaders;499499- rdev->r600_blit.primitives.set_vtx_resource = set_vtx_resource;500500- rdev->r600_blit.primitives.set_tex_resource = set_tex_resource;501501- rdev->r600_blit.primitives.set_scissors = set_scissors;502502- rdev->r600_blit.primitives.draw_auto = draw_auto;503503- rdev->r600_blit.primitives.set_default_state = set_default_state;504504-505505- rdev->r600_blit.ring_size_common = 8; /* sync semaphore */506506- rdev->r600_blit.ring_size_common += 40; /* shaders + def state */507507- rdev->r600_blit.ring_size_common += 5; /* done copy */508508- rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */509509-510510- rdev->r600_blit.ring_size_per_loop = 76;511511- /* set_render_target emits 2 extra dwords on rv6xx */512512- if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770)513513- rdev->r600_blit.ring_size_per_loop += 2;514514-515515- rdev->r600_blit.max_dim = 8192;516516-517517- rdev->r600_blit.state_offset = 0;518518-519519- if (rdev->family >= CHIP_RV770)520520- rdev->r600_blit.state_len = r7xx_default_size;521521- else522522- rdev->r600_blit.state_len = r6xx_default_size;523523-524524- dwords = rdev->r600_blit.state_len;525525- while (dwords & 0xf) {526526- packet2s[num_packet2s++] = cpu_to_le32(PACKET2(0));527527- dwords++;528528- }529529-530530- obj_size = dwords * 4;531531- obj_size = ALIGN(obj_size, 256);532532-533533- rdev->r600_blit.vs_offset = obj_size;534534- obj_size += r6xx_vs_size * 4;535535- obj_size = ALIGN(obj_size, 256);536536-537537- rdev->r600_blit.ps_offset = obj_size;538538- obj_size += r6xx_ps_size * 4;539539- obj_size = ALIGN(obj_size, 256);540540-541541- /* pin copy shader into vram if not already initialized */542542- if (rdev->r600_blit.shader_obj == NULL) {543543- r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true,544544- RADEON_GEM_DOMAIN_VRAM,545545- NULL, &rdev->r600_blit.shader_obj);546546- if (r) {547547- DRM_ERROR("r600 failed to allocate shader\n");548548- return r;549549- }550550-551551- r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);552552- if (unlikely(r != 0))553553- return r;554554- r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,555555- &rdev->r600_blit.shader_gpu_addr);556556- radeon_bo_unreserve(rdev->r600_blit.shader_obj);557557- if (r) {558558- dev_err(rdev->dev, "(%d) pin blit object failed\n", r);559559- return r;560560- }561561- }562562-563563- DRM_DEBUG("r6xx blit allocated bo %08x vs %08x ps %08x\n",564564- obj_size,565565- rdev->r600_blit.vs_offset, rdev->r600_blit.ps_offset);566566-567567- r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);568568- if (unlikely(r != 0))569569- return r;570570- r = radeon_bo_kmap(rdev->r600_blit.shader_obj, &ptr);571571- if (r) {572572- DRM_ERROR("failed to map blit object %d\n", r);573573- return r;574574- }575575- if (rdev->family >= CHIP_RV770)576576- memcpy_toio(ptr + rdev->r600_blit.state_offset,577577- r7xx_default_state, rdev->r600_blit.state_len * 4);578578- else579579- memcpy_toio(ptr + rdev->r600_blit.state_offset,580580- r6xx_default_state, rdev->r600_blit.state_len * 4);581581- if (num_packet2s)582582- memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),583583- packet2s, num_packet2s * 4);584584- for (i = 0; i < r6xx_vs_size; i++)585585- *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(r6xx_vs[i]);586586- for (i = 0; i < r6xx_ps_size; i++)587587- *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(r6xx_ps[i]);588588- radeon_bo_kunmap(rdev->r600_blit.shader_obj);589589- radeon_bo_unreserve(rdev->r600_blit.shader_obj);590590-591591- radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);592592- return 0;593593-}594594-595595-void r600_blit_fini(struct radeon_device *rdev)596596-{597597- int r;598598-599599- radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);600600- if (rdev->r600_blit.shader_obj == NULL)601601- return;602602- /* If we can't reserve the bo, unref should be enough to destroy603603- * it when it becomes idle.604604- */605605- r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);606606- if (!r) {607607- radeon_bo_unpin(rdev->r600_blit.shader_obj);608608- radeon_bo_unreserve(rdev->r600_blit.shader_obj);609609- }610610- radeon_bo_unref(&rdev->r600_blit.shader_obj);611611-}612612-613613-static unsigned r600_blit_create_rect(unsigned num_gpu_pages,614614- int *width, int *height, int max_dim)615615-{616616- unsigned max_pages;617617- unsigned pages = num_gpu_pages;618618- int w, h;619619-620620- if (num_gpu_pages == 0) {621621- /* not supposed to be called with no pages, but just in case */622622- h = 0;623623- w = 0;624624- pages = 0;625625- WARN_ON(1);626626- } else {627627- int rect_order = 2;628628- h = RECT_UNIT_H;629629- while (num_gpu_pages / rect_order) {630630- h *= 2;631631- rect_order *= 4;632632- if (h >= max_dim) {633633- h = max_dim;634634- break;635635- }636636- }637637- max_pages = (max_dim * h) / (RECT_UNIT_W * RECT_UNIT_H);638638- if (pages > max_pages)639639- pages = max_pages;640640- w = (pages * RECT_UNIT_W * RECT_UNIT_H) / h;641641- w = (w / RECT_UNIT_W) * RECT_UNIT_W;642642- pages = (w * h) / (RECT_UNIT_W * RECT_UNIT_H);643643- BUG_ON(pages == 0);644644- }645645-646646-647647- DRM_DEBUG("blit_rectangle: h=%d, w=%d, pages=%d\n", h, w, pages);648648-649649- /* return width and height only of the caller wants it */650650- if (height)651651- *height = h;652652- if (width)653653- *width = w;654654-655655- return pages;656656-}657657-658658-659659-int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages,660660- struct radeon_fence **fence, struct radeon_sa_bo **vb,661661- struct radeon_semaphore **sem)662662-{663663- struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];664664- int r;665665- int ring_size;666666- int num_loops = 0;667667- int dwords_per_loop = rdev->r600_blit.ring_size_per_loop;668668-669669- /* num loops */670670- while (num_gpu_pages) {671671- num_gpu_pages -=672672- r600_blit_create_rect(num_gpu_pages, NULL, NULL,673673- rdev->r600_blit.max_dim);674674- num_loops++;675675- }676676-677677- /* 48 bytes for vertex per loop */678678- r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, vb,679679- (num_loops*48)+256, 256, true);680680- if (r) {681681- return r;682682- }683683-684684- r = radeon_semaphore_create(rdev, sem);685685- if (r) {686686- radeon_sa_bo_free(rdev, vb, NULL);687687- return r;688688- }689689-690690- /* calculate number of loops correctly */691691- ring_size = num_loops * dwords_per_loop;692692- ring_size += rdev->r600_blit.ring_size_common;693693- r = radeon_ring_lock(rdev, ring, ring_size);694694- if (r) {695695- radeon_sa_bo_free(rdev, vb, NULL);696696- radeon_semaphore_free(rdev, sem, NULL);697697- return r;698698- }699699-700700- if (radeon_fence_need_sync(*fence, RADEON_RING_TYPE_GFX_INDEX)) {701701- radeon_semaphore_sync_rings(rdev, *sem, (*fence)->ring,702702- RADEON_RING_TYPE_GFX_INDEX);703703- radeon_fence_note_sync(*fence, RADEON_RING_TYPE_GFX_INDEX);704704- } else {705705- radeon_semaphore_free(rdev, sem, NULL);706706- }707707-708708- rdev->r600_blit.primitives.set_default_state(rdev);709709- rdev->r600_blit.primitives.set_shaders(rdev);710710- return 0;711711-}712712-713713-void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence **fence,714714- struct radeon_sa_bo *vb, struct radeon_semaphore *sem)715715-{716716- struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];717717- int r;718718-719719- r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX);720720- if (r) {721721- radeon_ring_unlock_undo(rdev, ring);722722- return;723723- }724724-725725- radeon_ring_unlock_commit(rdev, ring);726726- radeon_sa_bo_free(rdev, &vb, *fence);727727- radeon_semaphore_free(rdev, &sem, *fence);728728-}729729-730730-void r600_kms_blit_copy(struct radeon_device *rdev,731731- u64 src_gpu_addr, u64 dst_gpu_addr,732732- unsigned num_gpu_pages,733733- struct radeon_sa_bo *vb)734734-{735735- u64 vb_gpu_addr;736736- u32 *vb_cpu_addr;737737-738738- DRM_DEBUG("emitting copy %16llx %16llx %d\n",739739- src_gpu_addr, dst_gpu_addr, num_gpu_pages);740740- vb_cpu_addr = (u32 *)radeon_sa_bo_cpu_addr(vb);741741- vb_gpu_addr = radeon_sa_bo_gpu_addr(vb);742742-743743- while (num_gpu_pages) {744744- int w, h;745745- unsigned size_in_bytes;746746- unsigned pages_per_loop =747747- r600_blit_create_rect(num_gpu_pages, &w, &h,748748- rdev->r600_blit.max_dim);749749-750750- size_in_bytes = pages_per_loop * RADEON_GPU_PAGE_SIZE;751751- DRM_DEBUG("rectangle w=%d h=%d\n", w, h);752752-753753- vb_cpu_addr[0] = 0;754754- vb_cpu_addr[1] = 0;755755- vb_cpu_addr[2] = 0;756756- vb_cpu_addr[3] = 0;757757-758758- vb_cpu_addr[4] = 0;759759- vb_cpu_addr[5] = int2float(h);760760- vb_cpu_addr[6] = 0;761761- vb_cpu_addr[7] = int2float(h);762762-763763- vb_cpu_addr[8] = int2float(w);764764- vb_cpu_addr[9] = int2float(h);765765- vb_cpu_addr[10] = int2float(w);766766- vb_cpu_addr[11] = int2float(h);767767-768768- rdev->r600_blit.primitives.set_tex_resource(rdev, FMT_8_8_8_8,769769- w, h, w, src_gpu_addr, size_in_bytes);770770- rdev->r600_blit.primitives.set_render_target(rdev, COLOR_8_8_8_8,771771- w, h, dst_gpu_addr);772772- rdev->r600_blit.primitives.set_scissors(rdev, 0, 0, w, h);773773- rdev->r600_blit.primitives.set_vtx_resource(rdev, vb_gpu_addr);774774- rdev->r600_blit.primitives.draw_auto(rdev);775775- rdev->r600_blit.primitives.cp_set_surface_sync(rdev,776776- PACKET3_CB_ACTION_ENA | PACKET3_CB0_DEST_BASE_ENA,777777- size_in_bytes, dst_gpu_addr);778778-779779- vb_cpu_addr += 12;780780- vb_gpu_addr += 4*12;781781- src_gpu_addr += size_in_bytes;782782- dst_gpu_addr += size_in_bytes;783783- num_gpu_pages -= pages_per_loop;784784- }785785-}
···11-/*22- * Copyright 2009 Advanced Micro Devices, Inc.33- * Copyright 2009 Red Hat Inc.44- * Copyright 2012 Alcatel-Lucent, Inc.55- *66- * Permission is hereby granted, free of charge, to any person obtaining a77- * copy of this software and associated documentation files (the "Software"),88- * to deal in the Software without restriction, including without limitation99- * the rights to use, copy, modify, merge, publish, distribute, sublicense,1010- * and/or sell copies of the Software, and to permit persons to whom the1111- * Software is furnished to do so, subject to the following conditions:1212- *1313- * The above copyright notice and this permission notice (including the next1414- * paragraph) shall be included in all copies or substantial portions of the1515- * Software.1616- *1717- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR1818- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,1919- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL2020- * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR2121- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,2222- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER2323- * DEALINGS IN THE SOFTWARE.2424- *2525- */2626-2727-#ifndef __RADEON_BLIT_COMMON_H__2828-2929-#define DI_PT_RECTLIST 0x113030-#define DI_INDEX_SIZE_16_BIT 0x03131-#define DI_SRC_SEL_AUTO_INDEX 0x23232-3333-#define FMT_8 0x13434-#define FMT_5_6_5 0x83535-#define FMT_8_8_8_8 0x1a3636-#define COLOR_8 0x13737-#define COLOR_5_6_5 0x83838-#define COLOR_8_8_8_8 0x1a3939-4040-#define RECT_UNIT_H 324141-#define RECT_UNIT_W (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H)4242-4343-#define __RADEON_BLIT_COMMON_H__4444-#endif
-7
drivers/gpu/drm/radeon/rv770.c
···18521852 }1853185318541854 rv770_gpu_init(rdev);18551855- r = r600_blit_init(rdev);18561856- if (r) {18571857- r600_blit_fini(rdev);18581858- rdev->asic->copy.copy = NULL;18591859- dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);18601860- }1861185518621856 /* allocate wb buffer */18631857 r = radeon_wb_init(rdev);···2086209220872093void rv770_fini(struct radeon_device *rdev)20882094{20892089- r600_blit_fini(rdev);20902095 r700_cp_fini(rdev);20912096 r600_dma_fini(rdev);20922097 r600_irq_fini(rdev);