/* * Copyright 2008 Advanced Micro Devices, Inc. * Copyright 2008 Red Hat Inc. * Copyright 2009 Jerome Glisse. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Authors: Dave Airlie * Alex Deucher * Jerome Glisse */ #include <linux/kernel.h> #include "radeon.h" #include "radeon_asic.h" #include "r600.h" #include "r600d.h" #include "r600_reg_safe.h" static int r600_nomm; struct r600_cs_track { … }; #define FMT_8_BIT(fmt, vc) … #define FMT_16_BIT(fmt, vc) … #define FMT_24_BIT(fmt) … #define FMT_32_BIT(fmt, vc) … #define FMT_48_BIT(fmt) … #define FMT_64_BIT(fmt, vc) … #define FMT_96_BIT(fmt) … #define FMT_128_BIT(fmt, vc) … struct gpu_formats { … }; static const struct gpu_formats color_formats_table[] = …; bool r600_fmt_is_valid_color(u32 format) { … } bool r600_fmt_is_valid_texture(u32 format, enum radeon_family family) { … } int r600_fmt_get_blocksize(u32 format) { … } int r600_fmt_get_nblocksx(u32 format, u32 w) { … } int r600_fmt_get_nblocksy(u32 format, u32 h) { … } struct array_mode_checker { … }; /* returns alignment in pixels for pitch/height/depth and bytes for base */ static int r600_get_array_mode_alignment(struct array_mode_checker *values, u32 *pitch_align, u32 *height_align, u32 *depth_align, u64 *base_align) { … } static void r600_cs_track_init(struct r600_cs_track *track) { … } static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) { … } static int r600_cs_track_validate_db(struct radeon_cs_parser *p) { … } static int r600_cs_track_check(struct radeon_cs_parser *p) { … } /** * r600_cs_packet_parse_vline() - parse userspace VLINE packet * @p: parser structure holding parsing context. * * This is an R600-specific function for parsing VLINE packets. * Real work is done by r600_cs_common_vline_parse function. * Here we just set up ASIC-specific register table and call * the common implementation function. */ static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p) { … } /** * r600_cs_common_vline_parse() - common vline parser * @p: parser structure holding parsing context. * @vline_start_end: table of vline_start_end registers * @vline_status: table of vline_status registers * * Userspace sends a special sequence for VLINE waits. * PACKET0 - VLINE_START_END + value * PACKET3 - WAIT_REG_MEM poll vline status reg * RELOC (P3) - crtc_id in reloc. * * This function parses this and relocates the VLINE START END * and WAIT_REG_MEM packets to the correct crtc. * It also detects a switched off crtc and nulls out the * wait in that case. This function is common for all ASICs that * are R600 and newer. The parsing algorithm is the same, and only * differs in which registers are used. * * Caller is the ASIC-specific function which passes the parser * context and ASIC-specific register table */ int r600_cs_common_vline_parse(struct radeon_cs_parser *p, uint32_t *vline_start_end, uint32_t *vline_status) { … } static int r600_packet0_check(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt, unsigned idx, unsigned reg) { … } static int r600_cs_parse_packet0(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt) { … } /** * r600_cs_check_reg() - check if register is authorized or not * @p: parser structure holding parsing context * @reg: register we are testing * @idx: index into the cs buffer * * This function will test against r600_reg_safe_bm and return 0 * if register is safe. If register is not flag as safe this function * will test it against a list of register needing special handling. */ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) { … } unsigned r600_mip_minify(unsigned size, unsigned level) { … } static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, unsigned w0, unsigned h0, unsigned d0, unsigned nsamples, unsigned format, unsigned block_align, unsigned height_align, unsigned base_align, unsigned *l0_size, unsigned *mipmap_size) { … } /** * r600_check_texture_resource() - check if register is authorized or not * @p: parser structure holding parsing context * @idx: index into the cs buffer * @texture: texture's bo structure * @mipmap: mipmap's bo structure * @base_offset: base offset (used for error checking) * @mip_offset: mip offset (used for error checking) * @tiling_flags: tiling flags * * This function will check that the resource has valid field and that * the texture and mipmap bo object are big enough to cover this resource. */ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, struct radeon_bo *texture, struct radeon_bo *mipmap, u64 base_offset, u64 mip_offset, u32 tiling_flags) { … } static bool r600_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) { … } static int r600_packet3_check(struct radeon_cs_parser *p, struct radeon_cs_packet *pkt) { … } int r600_cs_parse(struct radeon_cs_parser *p) { … } /* * DMA */ /** * r600_dma_cs_next_reloc() - parse next reloc * @p: parser structure holding parsing context. * @cs_reloc: reloc information * * Return the next reloc, do bo validation and compute * GPU offset using the provided start. **/ int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, struct radeon_bo_list **cs_reloc) { … } #define GET_DMA_CMD(h) … #define GET_DMA_COUNT(h) … #define GET_DMA_T(h) … /** * r600_dma_cs_parse() - parse the DMA IB * @p: parser structure holding parsing context. * * Parses the DMA IB from the CS ioctl and updates * the GPU addresses based on the reloc information and * checks for errors. (R6xx-R7xx) * Returns 0 for success and an error on failure. **/ int r600_dma_cs_parse(struct radeon_cs_parser *p) { … }