From 5c0509f9c03755969df954832366cbdc7a48d13f Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Fri, 2 Oct 2009 23:48:42 +0000 Subject: [PATCH] - Fix the problem presented by r196988. svn merge was erroneously interrupted and after re-run new files were not added to repo though respective revisions were marked as merged. This commit presents latest versions of these files. --- etc/rc.d/static_arp | 74 + share/colldef/la_LN.ISO8859-13.src | 37 + share/mklocale/la_LN.ISO8859-13.src | 49 + share/monetdef/lv_LV.ISO8859-13.src | 36 + share/msgdef/lv_LV.ISO8859-13.src | 14 + share/msgdef/lv_LV.UTF-8.src | 14 + share/timedef/lv_LV.ISO8859-13.src | 101 ++ share/timedef/lv_LV.UTF-8.src | 101 ++ sys/dev/drm/r600_blit.c | 1990 +++++++++++++++++++++++++++ sys/dev/drm/radeon_cs.c | 856 ++++++++++++ 10 files changed, 3272 insertions(+) create mode 100644 etc/rc.d/static_arp create mode 100644 share/colldef/la_LN.ISO8859-13.src create mode 100644 share/mklocale/la_LN.ISO8859-13.src create mode 100644 share/monetdef/lv_LV.ISO8859-13.src create mode 100644 share/msgdef/lv_LV.ISO8859-13.src create mode 100644 share/msgdef/lv_LV.UTF-8.src create mode 100644 share/timedef/lv_LV.ISO8859-13.src create mode 100644 share/timedef/lv_LV.UTF-8.src create mode 100644 sys/dev/drm/r600_blit.c create mode 100644 sys/dev/drm/radeon_cs.c diff --git a/etc/rc.d/static_arp b/etc/rc.d/static_arp new file mode 100644 index 00000000000..6283b56ef08 --- /dev/null +++ b/etc/rc.d/static_arp @@ -0,0 +1,74 @@ +#!/bin/sh +# +# Copyright (c) 2009 Xin LI +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# Configure static ARP table +# +# $FreeBSD$ +# + +# PROVIDE: static_arp +# REQUIRE: netif +# KEYWORD: nojail + +. /etc/rc.subr +. /etc/network.subr + +name="static_arp" +start_cmd="static_arp_start" +stop_cmd="static_arp_stop" + +static_arp_start() +{ + local e arp_args + + if [ -n "${static_arp_pairs}" ]; then + echo -n 'Binding static ARP pair(s):' + for e in ${static_arp_pairs}; do + echo -n " ${e}" + eval arp_args=\$static_arp_${e} + arp -S ${arp_args} >/dev/null 2>&1 + done + echo '.' + fi +} + +static_arp_stop() +{ + local e arp_args + + if [ -n "${static_arp_pairs}" ]; then + echo -n 'Unbinding static ARP pair(s):' + for e in ${static_arp_pairs}; do + echo -n " ${e}" + eval arp_args=\$static_arp_${e} + arp -d ${arp_args%%[ ]*} > /dev/null 2>&1 + done + echo '.' + fi +} + +load_rc_config $name +run_rc_command "$1" diff --git a/share/colldef/la_LN.ISO8859-13.src b/share/colldef/la_LN.ISO8859-13.src new file mode 100644 index 00000000000..828e478131b --- /dev/null +++ b/share/colldef/la_LN.ISO8859-13.src @@ -0,0 +1,37 @@ +# Latin-7 / Baltic Rim (backward compatible with ASCII) +# +# $FreeBSD$ +# +charmap map.ISO8859-13 +order \ +# controls + ;...;;;...;;\ +# + ;;!;\";<"">;;\ + ;;;;\ + %;&;';\(;\);*;+;<-:>;<*X>;<.M>;\,;<,,>;<``>;<-->;<+->;-;.;<'.>;/;\ +# digits + 0;...;9;\ +# + :;\;;\<;=;>;<<<>;/>>;?;;;;\ +# capital + (A,,,,,);\ + B;(C,,);D;(E,,,,);\ + F;(G,);H;(I,,);Y;\ + J;(K,);(L,,);M;(N,,);(O,,,,,);\ + P;Q;(R,);(S,,);T;\ + (U,,,);\ + V;W;X;(Z,,,);\ +# + [;\\;];^;_;`;\ +# small + (a,,,,,);\ + b;(c,,);d;(e,,,,);\ + f;(g,);h;(i,,);y;\ + j;(k,);(l,,);m;(n,,);(o,,,,,);\ + p;q;(r,);(s,,,);t;\ + (u,,,);\ + v;w;x;(z,,,);\ +# + \{;|;;\};~;;
;;;;;<1S>;<2S>;<3S>;\ + <14>;<12>;<34> diff --git a/share/mklocale/la_LN.ISO8859-13.src b/share/mklocale/la_LN.ISO8859-13.src new file mode 100644 index 00000000000..ddd248f1cc1 --- /dev/null +++ b/share/mklocale/la_LN.ISO8859-13.src @@ -0,0 +1,49 @@ +/* + * LOCALE_CTYPE for the iso_8859_13 Locale + * + * $FreeBSD$ + */ + +ENCODING "NONE" +VARIABLE ISO 8859-13 Latin-7 character set + +# +# This is a comment +# +ALPHA 'A' - 'Z' 'a' - 'z' +ALPHA 0xaa 0xba 0xc0 - 0xd6 0xd8 - 0xde 0xe0 - 0xf6 0xf8 - 0xfe +CONTROL 0x00 - 0x1f 0x7f - 0x9f +DIGIT '0' - '9' +GRAPH 0x21 - 0x7e 0xa1 - 0xff +LOWER 'a' - 'z' +LOWER 0xba 0xdf - 0xf6 0xf8 - 0xfe +PUNCT 0x21 - 0x2f 0x3a - 0x40 0x5b - 0x60 0x7b - 0x7e +PUNCT 0xa1 - 0xa9 0xab - 0xb9 0xbb -0xbf 0xd7 0xdf 0xf7 0xff +SPACE 0x09 - 0x0d 0x20 0xa0 +UPPER 'A' - 'Z' +UPPER 0xaa 0xc0 - 0xd6 0xd8 - 0xde +XDIGIT '0' - '9' 'a' - 'f' 'A' - 'F' +BLANK ' ' '\t' 0xa0 +PRINT 0x20 - 0x7e 0xa0 - 0xff + +MAPLOWER <'A' - 'Z' : 'a'> +MAPLOWER <'a' - 'z' : 'a'> +MAPLOWER <0xaa 0xba> +MAPLOWER <0xba 0xba> +MAPLOWER <0xc0 - 0xd6 : 0xe0> +MAPLOWER <0xd8 - 0xde : 0xf8> +MAPLOWER <0xe0 - 0xf6 : 0xe0> +MAPLOWER <0xf8 - 0xfe : 0xf8> + +MAPUPPER <'A' - 'Z' : 'A'> +MAPUPPER <'a' - 'z' : 'A'> +MAPUPPER <0xaa 0xaa> +MAPUPPER <0xba 0xaa> +MAPUPPER <0xc0 - 0xd6 : 0xc0> +MAPUPPER <0xd8 - 0xdf : 0xd8> +MAPUPPER <0xe0 - 0xf6 : 0xc0> +MAPUPPER <0xf8 - 0xfe : 0xd8> + +TODIGIT <'0' - '9' : 0> +TODIGIT <'A' - 'F' : 10> +TODIGIT <'a' - 'f' : 10> diff --git a/share/monetdef/lv_LV.ISO8859-13.src b/share/monetdef/lv_LV.ISO8859-13.src new file mode 100644 index 00000000000..647c4e69935 --- /dev/null +++ b/share/monetdef/lv_LV.ISO8859-13.src @@ -0,0 +1,36 @@ +# $FreeBSD$ +# +# WARNING: spaces may be essential at the end of lines +# WARNING: empty lines are essential too +# +# int_curr_symbol (last character always SPACE) +LVL +# currency_symbol +Ls +# mon_decimal_point +, +# mon_thousands_sep + +# mon_grouping, separated by ; +3;3 +# positive_sign + +# negative_sign +- +# int_frac_digits +2 +# frac_digits +2 +# p_cs_precedes +0 +# p_sep_by_space +1 +# n_cs_precedes +0 +# n_sep_by_space +1 +# p_sign_posn +1 +# n_sign_posn +1 +# EOF diff --git a/share/msgdef/lv_LV.ISO8859-13.src b/share/msgdef/lv_LV.ISO8859-13.src new file mode 100644 index 00000000000..d744ad86b30 --- /dev/null +++ b/share/msgdef/lv_LV.ISO8859-13.src @@ -0,0 +1,14 @@ +# $FreeBSD$ +# +# WARNING: spaces may be essential at the end of lines +# WARNING: empty lines are essential too +# +# yesexpr +^[jJyY].* +# noexpr +^[nN].* +# yesstr +jâ +# nostr +nç +# EOF diff --git a/share/msgdef/lv_LV.UTF-8.src b/share/msgdef/lv_LV.UTF-8.src new file mode 100644 index 00000000000..85f1a73fc1e --- /dev/null +++ b/share/msgdef/lv_LV.UTF-8.src @@ -0,0 +1,14 @@ +# $FreeBSD$ +# +# WARNING: spaces may be essential at the end of lines +# WARNING: empty lines are essential too +# +# yesexpr +^[jJyY].* +# noexpr +^[nN].* +# yesstr +jā +# nostr +nē +# EOF diff --git a/share/timedef/lv_LV.ISO8859-13.src b/share/timedef/lv_LV.ISO8859-13.src new file mode 100644 index 00000000000..5e5e3d1f40d --- /dev/null +++ b/share/timedef/lv_LV.ISO8859-13.src @@ -0,0 +1,101 @@ +# $FreeBSD$ +# WARNING: spaces may be essential at the end of lines +# WARNING: empty lines are essential too +# +# Short month names +# +Jan +Feb +Mar +Apr +Mai +Jûn +Jûl +Aug +Sep +Okt +Nov +Dec +# +# Long month names +# +janvâris +februâris +marts +aprîlis +maijs +jûnijs +jûlijs +augusts +septembris +oktobris +novembris +decembris +# +# Short weekday names +# +Sv +Pr +Ot +Tr +Ct +Pk +Ss +# +# Long weekday names +# +Svçtdiena +Pirmdiena +Otrdiena +Treðdiena +Ceturtdiena +Piektdiena +Sestdiena +# +# X_fmt +# +%H:%M:%S +# +# x_fmt +# +%d/%m/%Y +# +# c_fmt +# %A, %Y m. %B %e d. %T +%e. %b, %Y. gads %X +# +# am +# + +# +# pm +# + +# +# date_fmt +# +%A, %Y. gada %e. %B %T %Z +# +# Long month names in alternative form +# +janvâris +februâris +marts +aprîlis +maijs +jûnijs +jûlijs +augusts +septembris +oktobris +novembris +decembris +# +# md_order +# +md +# +# ampm_fmt +# + +# EOF diff --git a/share/timedef/lv_LV.UTF-8.src b/share/timedef/lv_LV.UTF-8.src new file mode 100644 index 00000000000..56d1cb40927 --- /dev/null +++ b/share/timedef/lv_LV.UTF-8.src @@ -0,0 +1,101 @@ +# $FreeBSD$ +# WARNING: spaces may be essential at the end of lines +# WARNING: empty lines are essential too +# +# Short month names +# +Jan +Feb +Mar +Apr +Mai +JÅ«n +JÅ«l +Aug +Sep +Okt +Nov +Dec +# +# Long month names +# +janvāris +februāris +marts +aprÄ«lis +maijs +jÅ«nijs +jÅ«lijs +augusts +septembris +oktobris +novembris +decembris +# +# Short weekday names +# +Sv +Pr +Ot +Tr +Ct +Pk +Ss +# +# Long weekday names +# +Svētdiena +Pirmdiena +Otrdiena +TreÅ¡diena +Ceturtdiena +Piektdiena +Sestdiena +# +# X_fmt +# +%H:%M:%S +# +# x_fmt +# +%d/%m/%Y +# +# c_fmt +# %A, %Y m. %B %e d. %T +%e. %b, %Y. gads %X +# +# am +# + +# +# pm +# + +# +# date_fmt +# +%A, %Y. gada %e. %B %T %Z +# +# Long month names in alternative form +# +janvāris +februāris +marts +aprÄ«lis +maijs +jÅ«nijs +jÅ«lijs +augusts +septembris +oktobris +novembris +decembris +# +# md_order +# +md +# +# ampm_fmt +# + +# EOF diff --git a/sys/dev/drm/r600_blit.c b/sys/dev/drm/r600_blit.c new file mode 100644 index 00000000000..6443d843f98 --- /dev/null +++ b/sys/dev/drm/r600_blit.c @@ -0,0 +1,1990 @@ +/*- + * Copyright 2009 Advanced Micro Devices, Inc. + * + * 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 (including the next + * paragraph) 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) AND/OR ITS SUPPLIERS 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: + * Alex Deucher + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "dev/drm/drmP.h" +#include "dev/drm/drm.h" +#include "dev/drm/radeon_drm.h" +#include "dev/drm/radeon_drv.h" + +static u32 r6xx_default_state[] = +{ + 0xc0002400, + 0x00000000, + 0xc0012800, + 0x80000000, + 0x80000000, + 0xc0004600, + 0x00000016, + 0xc0016800, + 0x00000010, + 0x00028000, + 0xc0016800, + 0x00000010, + 0x00008000, + 0xc0016800, + 0x00000542, + 0x07000003, + 0xc0016800, + 0x000005c5, + 0x00000000, + 0xc0016800, + 0x00000363, + 0x00000000, + 0xc0016800, + 0x0000060c, + 0x82000000, + 0xc0016800, + 0x0000060e, + 0x01020204, + 0xc0016f00, + 0x00000000, + 0x00000000, + 0xc0016f00, + 0x00000001, + 0x00000000, + 0xc0096900, + 0x0000022a, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0016900, + 0x00000004, + 0x00000000, + 0xc0016900, + 0x0000000a, + 0x00000000, + 0xc0016900, + 0x0000000b, + 0x00000000, + 0xc0016900, + 0x0000010c, + 0x00000000, + 0xc0016900, + 0x0000010d, + 0x00000000, + 0xc0016900, + 0x00000200, + 0x00000000, + 0xc0016900, + 0x00000343, + 0x00000060, + 0xc0016900, + 0x00000344, + 0x00000040, + 0xc0016900, + 0x00000351, + 0x0000aa00, + 0xc0016900, + 0x00000104, + 0x00000000, + 0xc0016900, + 0x0000010e, + 0x00000000, + 0xc0046900, + 0x00000105, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0036900, + 0x00000109, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0046900, + 0x0000030c, + 0x01000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0046900, + 0x00000048, + 0x3f800000, + 0x00000000, + 0x3f800000, + 0x3f800000, + 0xc0016900, + 0x0000008e, + 0x0000000f, + 0xc0016900, + 0x00000080, + 0x00000000, + 0xc0016900, + 0x00000083, + 0x0000ffff, + 0xc0016900, + 0x00000084, + 0x00000000, + 0xc0016900, + 0x00000085, + 0x20002000, + 0xc0016900, + 0x00000086, + 0x00000000, + 0xc0016900, + 0x00000087, + 0x20002000, + 0xc0016900, + 0x00000088, + 0x00000000, + 0xc0016900, + 0x00000089, + 0x20002000, + 0xc0016900, + 0x0000008a, + 0x00000000, + 0xc0016900, + 0x0000008b, + 0x20002000, + 0xc0016900, + 0x0000008c, + 0x00000000, + 0xc0016900, + 0x00000094, + 0x80000000, + 0xc0016900, + 0x00000095, + 0x20002000, + 0xc0026900, + 0x000000b4, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x00000096, + 0x80000000, + 0xc0016900, + 0x00000097, + 0x20002000, + 0xc0026900, + 0x000000b6, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x00000098, + 0x80000000, + 0xc0016900, + 0x00000099, + 0x20002000, + 0xc0026900, + 0x000000b8, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x0000009a, + 0x80000000, + 0xc0016900, + 0x0000009b, + 0x20002000, + 0xc0026900, + 0x000000ba, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x0000009c, + 0x80000000, + 0xc0016900, + 0x0000009d, + 0x20002000, + 0xc0026900, + 0x000000bc, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x0000009e, + 0x80000000, + 0xc0016900, + 0x0000009f, + 0x20002000, + 0xc0026900, + 0x000000be, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a0, + 0x80000000, + 0xc0016900, + 0x000000a1, + 0x20002000, + 0xc0026900, + 0x000000c0, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a2, + 0x80000000, + 0xc0016900, + 0x000000a3, + 0x20002000, + 0xc0026900, + 0x000000c2, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a4, + 0x80000000, + 0xc0016900, + 0x000000a5, + 0x20002000, + 0xc0026900, + 0x000000c4, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a6, + 0x80000000, + 0xc0016900, + 0x000000a7, + 0x20002000, + 0xc0026900, + 0x000000c6, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a8, + 0x80000000, + 0xc0016900, + 0x000000a9, + 0x20002000, + 0xc0026900, + 0x000000c8, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000aa, + 0x80000000, + 0xc0016900, + 0x000000ab, + 0x20002000, + 0xc0026900, + 0x000000ca, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000ac, + 0x80000000, + 0xc0016900, + 0x000000ad, + 0x20002000, + 0xc0026900, + 0x000000cc, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000ae, + 0x80000000, + 0xc0016900, + 0x000000af, + 0x20002000, + 0xc0026900, + 0x000000ce, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000b0, + 0x80000000, + 0xc0016900, + 0x000000b1, + 0x20002000, + 0xc0026900, + 0x000000d0, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000b2, + 0x80000000, + 0xc0016900, + 0x000000b3, + 0x20002000, + 0xc0026900, + 0x000000d2, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x00000293, + 0x00004010, + 0xc0016900, + 0x00000300, + 0x00000000, + 0xc0016900, + 0x00000301, + 0x00000000, + 0xc0016900, + 0x00000312, + 0xffffffff, + 0xc0016900, + 0x00000307, + 0x00000000, + 0xc0016900, + 0x00000308, + 0x00000000, + 0xc0016900, + 0x00000283, + 0x00000000, + 0xc0016900, + 0x00000292, + 0x00000000, + 0xc0066900, + 0x0000010f, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0016900, + 0x00000206, + 0x00000000, + 0xc0016900, + 0x00000207, + 0x00000000, + 0xc0016900, + 0x00000208, + 0x00000000, + 0xc0046900, + 0x00000303, + 0x3f800000, + 0x3f800000, + 0x3f800000, + 0x3f800000, + 0xc0016900, + 0x00000205, + 0x00000004, + 0xc0016900, + 0x00000280, + 0x00000000, + 0xc0016900, + 0x00000281, + 0x00000000, + 0xc0016900, + 0x0000037e, + 0x00000000, + 0xc0016900, + 0x00000382, + 0x00000000, + 0xc0016900, + 0x00000380, + 0x00000000, + 0xc0016900, + 0x00000383, + 0x00000000, + 0xc0016900, + 0x00000381, + 0x00000000, + 0xc0016900, + 0x00000282, + 0x00000008, + 0xc0016900, + 0x00000302, + 0x0000002d, + 0xc0016900, + 0x0000037f, + 0x00000000, + 0xc0016900, + 0x000001b2, + 0x00000000, + 0xc0016900, + 0x000001b6, + 0x00000000, + 0xc0016900, + 0x000001b7, + 0x00000000, + 0xc0016900, + 0x000001b8, + 0x00000000, + 0xc0016900, + 0x000001b9, + 0x00000000, + 0xc0016900, + 0x00000225, + 0x00000000, + 0xc0016900, + 0x00000229, + 0x00000000, + 0xc0016900, + 0x00000237, + 0x00000000, + 0xc0016900, + 0x00000100, + 0x00000800, + 0xc0016900, + 0x00000101, + 0x00000000, + 0xc0016900, + 0x00000102, + 0x00000000, + 0xc0016900, + 0x000002a8, + 0x00000000, + 0xc0016900, + 0x000002a9, + 0x00000000, + 0xc0016900, + 0x00000103, + 0x00000000, + 0xc0016900, + 0x00000284, + 0x00000000, + 0xc0016900, + 0x00000290, + 0x00000000, + 0xc0016900, + 0x00000285, + 0x00000000, + 0xc0016900, + 0x00000286, + 0x00000000, + 0xc0016900, + 0x00000287, + 0x00000000, + 0xc0016900, + 0x00000288, + 0x00000000, + 0xc0016900, + 0x00000289, + 0x00000000, + 0xc0016900, + 0x0000028a, + 0x00000000, + 0xc0016900, + 0x0000028b, + 0x00000000, + 0xc0016900, + 0x0000028c, + 0x00000000, + 0xc0016900, + 0x0000028d, + 0x00000000, + 0xc0016900, + 0x0000028e, + 0x00000000, + 0xc0016900, + 0x0000028f, + 0x00000000, + 0xc0016900, + 0x000002a1, + 0x00000000, + 0xc0016900, + 0x000002a5, + 0x00000000, + 0xc0016900, + 0x000002ac, + 0x00000000, + 0xc0016900, + 0x000002ad, + 0x00000000, + 0xc0016900, + 0x000002ae, + 0x00000000, + 0xc0016900, + 0x000002c8, + 0x00000000, + 0xc0016900, + 0x00000206, + 0x00000100, + 0xc0016900, + 0x00000204, + 0x00010000, + 0xc0036e00, + 0x00000000, + 0x00000012, + 0x00000000, + 0x00000000, + 0xc0016900, + 0x0000008f, + 0x0000000f, + 0xc0016900, + 0x000001e8, + 0x00000001, + 0xc0016900, + 0x00000202, + 0x00cc0000, + 0xc0016900, + 0x00000205, + 0x00000244, + 0xc0016900, + 0x00000203, + 0x00000210, + 0xc0016900, + 0x000001b1, + 0x00000000, + 0xc0016900, + 0x00000185, + 0x00000000, + 0xc0016900, + 0x000001b3, + 0x00000001, + 0xc0016900, + 0x000001b4, + 0x00000000, + 0xc0016900, + 0x00000191, + 0x00000b00, + 0xc0016900, + 0x000001b5, + 0x00000000, +}; + +static u32 r7xx_default_state[] = +{ + 0xc0012800, + 0x80000000, + 0x80000000, + 0xc0004600, + 0x00000016, + 0xc0016800, + 0x00000010, + 0x00028000, + 0xc0016800, + 0x00000010, + 0x00008000, + 0xc0016800, + 0x00000542, + 0x07000002, + 0xc0016800, + 0x000005c5, + 0x00000000, + 0xc0016800, + 0x00000363, + 0x00004000, + 0xc0016800, + 0x0000060c, + 0x00000000, + 0xc0016800, + 0x0000060e, + 0x00420204, + 0xc0016f00, + 0x00000000, + 0x00000000, + 0xc0016f00, + 0x00000001, + 0x00000000, + 0xc0096900, + 0x0000022a, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0016900, + 0x00000004, + 0x00000000, + 0xc0016900, + 0x0000000a, + 0x00000000, + 0xc0016900, + 0x0000000b, + 0x00000000, + 0xc0016900, + 0x0000010c, + 0x00000000, + 0xc0016900, + 0x0000010d, + 0x00000000, + 0xc0016900, + 0x00000200, + 0x00000000, + 0xc0016900, + 0x00000343, + 0x00000060, + 0xc0016900, + 0x00000344, + 0x00000000, + 0xc0016900, + 0x00000351, + 0x0000aa00, + 0xc0016900, + 0x00000104, + 0x00000000, + 0xc0016900, + 0x0000010e, + 0x00000000, + 0xc0046900, + 0x00000105, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0046900, + 0x0000030c, + 0x01000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0016900, + 0x0000008e, + 0x0000000f, + 0xc0016900, + 0x00000080, + 0x00000000, + 0xc0016900, + 0x00000083, + 0x0000ffff, + 0xc0016900, + 0x00000084, + 0x00000000, + 0xc0016900, + 0x00000085, + 0x20002000, + 0xc0016900, + 0x00000086, + 0x00000000, + 0xc0016900, + 0x00000087, + 0x20002000, + 0xc0016900, + 0x00000088, + 0x00000000, + 0xc0016900, + 0x00000089, + 0x20002000, + 0xc0016900, + 0x0000008a, + 0x00000000, + 0xc0016900, + 0x0000008b, + 0x20002000, + 0xc0016900, + 0x0000008c, + 0xaaaaaaaa, + 0xc0016900, + 0x00000094, + 0x80000000, + 0xc0016900, + 0x00000095, + 0x20002000, + 0xc0026900, + 0x000000b4, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x00000096, + 0x80000000, + 0xc0016900, + 0x00000097, + 0x20002000, + 0xc0026900, + 0x000000b6, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x00000098, + 0x80000000, + 0xc0016900, + 0x00000099, + 0x20002000, + 0xc0026900, + 0x000000b8, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x0000009a, + 0x80000000, + 0xc0016900, + 0x0000009b, + 0x20002000, + 0xc0026900, + 0x000000ba, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x0000009c, + 0x80000000, + 0xc0016900, + 0x0000009d, + 0x20002000, + 0xc0026900, + 0x000000bc, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x0000009e, + 0x80000000, + 0xc0016900, + 0x0000009f, + 0x20002000, + 0xc0026900, + 0x000000be, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a0, + 0x80000000, + 0xc0016900, + 0x000000a1, + 0x20002000, + 0xc0026900, + 0x000000c0, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a2, + 0x80000000, + 0xc0016900, + 0x000000a3, + 0x20002000, + 0xc0026900, + 0x000000c2, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a4, + 0x80000000, + 0xc0016900, + 0x000000a5, + 0x20002000, + 0xc0026900, + 0x000000c4, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a6, + 0x80000000, + 0xc0016900, + 0x000000a7, + 0x20002000, + 0xc0026900, + 0x000000c6, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000a8, + 0x80000000, + 0xc0016900, + 0x000000a9, + 0x20002000, + 0xc0026900, + 0x000000c8, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000aa, + 0x80000000, + 0xc0016900, + 0x000000ab, + 0x20002000, + 0xc0026900, + 0x000000ca, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000ac, + 0x80000000, + 0xc0016900, + 0x000000ad, + 0x20002000, + 0xc0026900, + 0x000000cc, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000ae, + 0x80000000, + 0xc0016900, + 0x000000af, + 0x20002000, + 0xc0026900, + 0x000000ce, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000b0, + 0x80000000, + 0xc0016900, + 0x000000b1, + 0x20002000, + 0xc0026900, + 0x000000d0, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x000000b2, + 0x80000000, + 0xc0016900, + 0x000000b3, + 0x20002000, + 0xc0026900, + 0x000000d2, + 0x00000000, + 0x3f800000, + 0xc0016900, + 0x00000293, + 0x00514000, + 0xc0016900, + 0x00000300, + 0x00000000, + 0xc0016900, + 0x00000301, + 0x00000000, + 0xc0016900, + 0x00000312, + 0xffffffff, + 0xc0016900, + 0x00000307, + 0x00000000, + 0xc0016900, + 0x00000308, + 0x00000000, + 0xc0016900, + 0x00000283, + 0x00000000, + 0xc0016900, + 0x00000292, + 0x00000000, + 0xc0066900, + 0x0000010f, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xc0016900, + 0x00000206, + 0x00000000, + 0xc0016900, + 0x00000207, + 0x00000000, + 0xc0016900, + 0x00000208, + 0x00000000, + 0xc0046900, + 0x00000303, + 0x3f800000, + 0x3f800000, + 0x3f800000, + 0x3f800000, + 0xc0016900, + 0x00000205, + 0x00000004, + 0xc0016900, + 0x00000280, + 0x00000000, + 0xc0016900, + 0x00000281, + 0x00000000, + 0xc0016900, + 0x0000037e, + 0x00000000, + 0xc0016900, + 0x00000382, + 0x00000000, + 0xc0016900, + 0x00000380, + 0x00000000, + 0xc0016900, + 0x00000383, + 0x00000000, + 0xc0016900, + 0x00000381, + 0x00000000, + 0xc0016900, + 0x00000282, + 0x00000008, + 0xc0016900, + 0x00000302, + 0x0000002d, + 0xc0016900, + 0x0000037f, + 0x00000000, + 0xc0016900, + 0x000001b2, + 0x00000001, + 0xc0016900, + 0x000001b6, + 0x00000000, + 0xc0016900, + 0x000001b7, + 0x00000000, + 0xc0016900, + 0x000001b8, + 0x00000000, + 0xc0016900, + 0x000001b9, + 0x00000000, + 0xc0016900, + 0x00000225, + 0x00000000, + 0xc0016900, + 0x00000229, + 0x00000000, + 0xc0016900, + 0x00000237, + 0x00000000, + 0xc0016900, + 0x00000100, + 0x00000800, + 0xc0016900, + 0x00000101, + 0x00000000, + 0xc0016900, + 0x00000102, + 0x00000000, + 0xc0016900, + 0x000002a8, + 0x00000000, + 0xc0016900, + 0x000002a9, + 0x00000000, + 0xc0016900, + 0x00000103, + 0x00000000, + 0xc0016900, + 0x00000284, + 0x00000000, + 0xc0016900, + 0x00000290, + 0x00000000, + 0xc0016900, + 0x00000285, + 0x00000000, + 0xc0016900, + 0x00000286, + 0x00000000, + 0xc0016900, + 0x00000287, + 0x00000000, + 0xc0016900, + 0x00000288, + 0x00000000, + 0xc0016900, + 0x00000289, + 0x00000000, + 0xc0016900, + 0x0000028a, + 0x00000000, + 0xc0016900, + 0x0000028b, + 0x00000000, + 0xc0016900, + 0x0000028c, + 0x00000000, + 0xc0016900, + 0x0000028d, + 0x00000000, + 0xc0016900, + 0x0000028e, + 0x00000000, + 0xc0016900, + 0x0000028f, + 0x00000000, + 0xc0016900, + 0x000002a1, + 0x00000000, + 0xc0016900, + 0x000002a5, + 0x00000000, + 0xc0016900, + 0x000002ac, + 0x00000000, + 0xc0016900, + 0x000002ad, + 0x00000000, + 0xc0016900, + 0x000002ae, + 0x00000000, + 0xc0016900, + 0x000002c8, + 0x00000000, + 0xc0016900, + 0x00000206, + 0x00000100, + 0xc0016900, + 0x00000204, + 0x00010000, + 0xc0036e00, + 0x00000000, + 0x00000012, + 0x00000000, + 0x00000000, + 0xc0016900, + 0x0000008f, + 0x0000000f, + 0xc0016900, + 0x000001e8, + 0x00000001, + 0xc0016900, + 0x00000202, + 0x00cc0000, + 0xc0016900, + 0x00000205, + 0x00000244, + 0xc0016900, + 0x00000203, + 0x00000210, + 0xc0016900, + 0x000001b1, + 0x00000000, + 0xc0016900, + 0x00000185, + 0x00000000, + 0xc0016900, + 0x000001b3, + 0x00000001, + 0xc0016900, + 0x000001b4, + 0x00000000, + 0xc0016900, + 0x00000191, + 0x00000b00, + 0xc0016900, + 0x000001b5, + 0x00000000, +}; + +/* same for r6xx/r7xx */ +static u32 r6xx_vs[] = +{ + 0x00000004, + 0x81000000, + 0x0000203c, + 0x94000b08, + 0x00004000, + 0x14200b1a, + 0x00000000, + 0x00000000, + 0x3c000000, + 0x68cd1000, + 0x00080000, + 0x00000000, +}; + +static u32 r6xx_ps[] = +{ + 0x00000002, + 0x80800000, + 0x00000000, + 0x94200688, + 0x00000010, + 0x000d1000, + 0xb0800000, + 0x00000000, +}; + +#define DI_PT_RECTLIST 0x11 +#define DI_INDEX_SIZE_16_BIT 0x0 +#define DI_SRC_SEL_AUTO_INDEX 0x2 + +#define FMT_8 1 +#define FMT_5_6_5 8 +#define FMT_8_8_8_8 0x1a +#define COLOR_8 1 +#define COLOR_5_6_5 8 +#define COLOR_8_8_8_8 0x1a + +#define R600_CB0_DEST_BASE_ENA (1 << 6) +#define R600_TC_ACTION_ENA (1 << 23) +#define R600_VC_ACTION_ENA (1 << 24) +#define R600_CB_ACTION_ENA (1 << 25) +#define R600_DB_ACTION_ENA (1 << 26) +#define R600_SH_ACTION_ENA (1 << 27) +#define R600_SMX_ACTION_ENA (1 << 28) + +#define R600_CB_COLOR0_SIZE 0x28060 +#define R600_CB_COLOR0_VIEW 0x28080 +#define R600_CB_COLOR0_INFO 0x280a0 +#define R600_CB_COLOR0_TILE 0x280c0 +#define R600_CB_COLOR0_FRAG 0x280e0 +#define R600_CB_COLOR0_MASK 0x28100 + +#define R600_SQ_PGM_START_VS 0x28858 +#define R600_SQ_PGM_RESOURCES_VS 0x28868 +#define R600_SQ_PGM_CF_OFFSET_VS 0x288d0 +#define R600_SQ_PGM_START_PS 0x28840 +#define R600_SQ_PGM_RESOURCES_PS 0x28850 +#define R600_SQ_PGM_EXPORTS_PS 0x28854 +#define R600_SQ_PGM_CF_OFFSET_PS 0x288cc + +#define R600_VGT_PRIMITIVE_TYPE 0x8958 + +#define R600_PA_SC_SCREEN_SCISSOR_TL 0x28030 +#define R600_PA_SC_GENERIC_SCISSOR_TL 0x28240 +#define R600_PA_SC_WINDOW_SCISSOR_TL 0x28204 + +#define R600_SQ_TEX_VTX_INVALID_TEXTURE 0x0 +#define R600_SQ_TEX_VTX_INVALID_BUFFER 0x1 +#define R600_SQ_TEX_VTX_VALID_TEXTURE 0x2 +#define R600_SQ_TEX_VTX_VALID_BUFFER 0x3 + +/* packet 3 type offsets */ +#define R600_SET_CONFIG_REG_OFFSET 0x00008000 +#define R600_SET_CONFIG_REG_END 0x0000ac00 +#define R600_SET_CONTEXT_REG_OFFSET 0x00028000 +#define R600_SET_CONTEXT_REG_END 0x00029000 +#define R600_SET_ALU_CONST_OFFSET 0x00030000 +#define R600_SET_ALU_CONST_END 0x00032000 +#define R600_SET_RESOURCE_OFFSET 0x00038000 +#define R600_SET_RESOURCE_END 0x0003c000 +#define R600_SET_SAMPLER_OFFSET 0x0003c000 +#define R600_SET_SAMPLER_END 0x0003cff0 +#define R600_SET_CTL_CONST_OFFSET 0x0003cff0 +#define R600_SET_CTL_CONST_END 0x0003e200 +#define R600_SET_LOOP_CONST_OFFSET 0x0003e200 +#define R600_SET_LOOP_CONST_END 0x0003e380 +#define R600_SET_BOOL_CONST_OFFSET 0x0003e380 +#define R600_SET_BOOL_CONST_END 0x00040000 + +/* Packet 3 types */ +#define R600_IT_INDIRECT_BUFFER_END 0x00001700 +#define R600_IT_SET_PREDICATION 0x00002000 +#define R600_IT_REG_RMW 0x00002100 +#define R600_IT_COND_EXEC 0x00002200 +#define R600_IT_PRED_EXEC 0x00002300 +#define R600_IT_START_3D_CMDBUF 0x00002400 +#define R600_IT_DRAW_INDEX_2 0x00002700 +#define R600_IT_CONTEXT_CONTROL 0x00002800 +#define R600_IT_DRAW_INDEX_IMMD_BE 0x00002900 +#define R600_IT_INDEX_TYPE 0x00002A00 +#define R600_IT_DRAW_INDEX 0x00002B00 +#define R600_IT_DRAW_INDEX_AUTO 0x00002D00 +#define R600_IT_DRAW_INDEX_IMMD 0x00002E00 +#define R600_IT_NUM_INSTANCES 0x00002F00 +#define R600_IT_STRMOUT_BUFFER_UPDATE 0x00003400 +#define R600_IT_INDIRECT_BUFFER_MP 0x00003800 +#define R600_IT_MEM_SEMAPHORE 0x00003900 +#define R600_IT_MPEG_INDEX 0x00003A00 +#define R600_IT_WAIT_REG_MEM 0x00003C00 +#define R600_IT_MEM_WRITE 0x00003D00 +#define R600_IT_INDIRECT_BUFFER 0x00003200 +#define R600_IT_CP_INTERRUPT 0x00004000 +#define R600_IT_SURFACE_SYNC 0x00004300 +#define R600_IT_ME_INITIALIZE 0x00004400 +#define R600_IT_COND_WRITE 0x00004500 +#define R600_IT_EVENT_WRITE 0x00004600 +#define R600_IT_EVENT_WRITE_EOP 0x00004700 +#define R600_IT_ONE_REG_WRITE 0x00005700 +#define R600_IT_SET_CONFIG_REG 0x00006800 +#define R600_IT_SET_CONTEXT_REG 0x00006900 +#define R600_IT_SET_ALU_CONST 0x00006A00 +#define R600_IT_SET_BOOL_CONST 0x00006B00 +#define R600_IT_SET_LOOP_CONST 0x00006C00 +#define R600_IT_SET_RESOURCE 0x00006D00 +#define R600_IT_SET_SAMPLER 0x00006E00 +#define R600_IT_SET_CTL_CONST 0x00006F00 +#define R600_IT_SURFACE_BASE_UPDATE 0x00007300 + +static inline void +set_render_target(drm_radeon_private_t *dev_priv, int format, int w, int h, u64 gpu_addr) +{ + u32 cb_color_info; + int pitch, slice; + RING_LOCALS; + DRM_DEBUG("\n"); + + h = (h + 7) & ~7; + if (h < 8) + h = 8; + + cb_color_info = ((format << 2) | (1 << 27)); + pitch = (w / 8) - 1; + slice = ((w * h) / 64) - 1; + + if (((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_R600) && + ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770)) { + BEGIN_RING(21 + 2); + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_CB_COLOR0_BASE - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(gpu_addr >> 8); + OUT_RING(CP_PACKET3(R600_IT_SURFACE_BASE_UPDATE, 0)); + OUT_RING(2 << 0); + } else { + BEGIN_RING(21); + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_CB_COLOR0_BASE - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(gpu_addr >> 8); + } + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_CB_COLOR0_SIZE - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING((pitch << 0) | (slice << 10)); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_CB_COLOR0_VIEW - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(0); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_CB_COLOR0_INFO - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(cb_color_info); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_CB_COLOR0_TILE - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(0); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_CB_COLOR0_FRAG - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(0); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_CB_COLOR0_MASK - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(0); + + ADVANCE_RING(); +} + +static inline void +cp_set_surface_sync(drm_radeon_private_t *dev_priv, + u32 sync_type, u32 size, u64 mc_addr) +{ + u32 cp_coher_size; + RING_LOCALS; + DRM_DEBUG("\n"); + + if (size == 0xffffffff) + cp_coher_size = 0xffffffff; + else + cp_coher_size = ((size + 255) >> 8); + + BEGIN_RING(5); + OUT_RING(CP_PACKET3(R600_IT_SURFACE_SYNC, 3)); + OUT_RING(sync_type); + OUT_RING(cp_coher_size); + OUT_RING((mc_addr >> 8)); + OUT_RING(10); /* poll interval */ + ADVANCE_RING(); +} + +static inline void +set_shaders(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + u64 gpu_addr; + int shader_size, i; + u32 *vs, *ps; + uint32_t sq_pgm_resources; + RING_LOCALS; + DRM_DEBUG("\n"); + + /* load shaders */ + vs = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset); + ps = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset + 256); + + shader_size = sizeof(r6xx_vs) / 4; + for (i= 0; i < shader_size; i++) + vs[i] = r6xx_vs[i]; + shader_size = sizeof(r6xx_ps) / 4; + for (i= 0; i < shader_size; i++) + ps[i] = r6xx_ps[i]; + + dev_priv->blit_vb->used = 512; + + gpu_addr = dev_priv->gart_buffers_offset + dev_priv->blit_vb->offset; + + /* setup shader regs */ + sq_pgm_resources = (1 << 0); + + BEGIN_RING(9 + 12); + /* VS */ + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_SQ_PGM_START_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(gpu_addr >> 8); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_SQ_PGM_RESOURCES_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(sq_pgm_resources); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_SQ_PGM_CF_OFFSET_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(0); + + /* PS */ + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_SQ_PGM_START_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING((gpu_addr + 256) >> 8); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_SQ_PGM_RESOURCES_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(sq_pgm_resources | (1 << 28)); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_SQ_PGM_EXPORTS_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(2); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); + OUT_RING((R600_SQ_PGM_CF_OFFSET_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING(0); + ADVANCE_RING(); + + cp_set_surface_sync(dev_priv, + R600_SH_ACTION_ENA, 512, gpu_addr); +} + +static inline void +set_vtx_resource(drm_radeon_private_t *dev_priv, u64 gpu_addr) +{ + uint32_t sq_vtx_constant_word2; + RING_LOCALS; + DRM_DEBUG("\n"); + + sq_vtx_constant_word2 = (((gpu_addr >> 32) & 0xff) | (16 << 8)); + + BEGIN_RING(9); + OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); + OUT_RING(0x460); + OUT_RING(gpu_addr & 0xffffffff); + OUT_RING(48 - 1); + OUT_RING(sq_vtx_constant_word2); + OUT_RING(1 << 0); + OUT_RING(0); + OUT_RING(0); + OUT_RING(R600_SQ_TEX_VTX_VALID_BUFFER << 30); + ADVANCE_RING(); + + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || + /*((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) ||*/ + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) + cp_set_surface_sync(dev_priv, + R600_TC_ACTION_ENA, 48, gpu_addr); + else + cp_set_surface_sync(dev_priv, + R600_VC_ACTION_ENA, 48, gpu_addr); +} + +static inline void +set_tex_resource(drm_radeon_private_t *dev_priv, + int format, int w, int h, int pitch, u64 gpu_addr) +{ + uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4; + RING_LOCALS; + DRM_DEBUG("\n"); + + if (h < 1) + h = 1; + + sq_tex_resource_word0 = (1 << 0); + sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) | + ((w - 1) << 19)); + + sq_tex_resource_word1 = (format << 26); + sq_tex_resource_word1 |= ((h - 1) << 0); + + sq_tex_resource_word4 = ((1 << 14) | + (0 << 16) | + (1 << 19) | + (2 << 22) | + (3 << 25)); + + BEGIN_RING(9); + OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); + OUT_RING(0); + OUT_RING(sq_tex_resource_word0); + OUT_RING(sq_tex_resource_word1); + OUT_RING(gpu_addr >> 8); + OUT_RING(gpu_addr >> 8); + OUT_RING(sq_tex_resource_word4); + OUT_RING(0); + OUT_RING(R600_SQ_TEX_VTX_VALID_TEXTURE << 30); + ADVANCE_RING(); + +} + +static inline void +set_scissors(drm_radeon_private_t *dev_priv, int x1, int y1, int x2, int y2) +{ + RING_LOCALS; + DRM_DEBUG("\n"); + + BEGIN_RING(12); + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2)); + OUT_RING((R600_PA_SC_SCREEN_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING((x1 << 0) | (y1 << 16)); + OUT_RING((x2 << 0) | (y2 << 16)); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2)); + OUT_RING((R600_PA_SC_GENERIC_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING((x1 << 0) | (y1 << 16) | (1 << 31)); + OUT_RING((x2 << 0) | (y2 << 16)); + + OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2)); + OUT_RING((R600_PA_SC_WINDOW_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2); + OUT_RING((x1 << 0) | (y1 << 16) | (1 << 31)); + OUT_RING((x2 << 0) | (y2 << 16)); + ADVANCE_RING(); +} + +static inline void +draw_auto(drm_radeon_private_t *dev_priv) +{ + RING_LOCALS; + DRM_DEBUG("\n"); + + BEGIN_RING(10); + OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); + OUT_RING((R600_VGT_PRIMITIVE_TYPE - R600_SET_CONFIG_REG_OFFSET) >> 2); + OUT_RING(DI_PT_RECTLIST); + + OUT_RING(CP_PACKET3(R600_IT_INDEX_TYPE, 0)); + OUT_RING(DI_INDEX_SIZE_16_BIT); + + OUT_RING(CP_PACKET3(R600_IT_NUM_INSTANCES, 0)); + OUT_RING(1); + + OUT_RING(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1)); + OUT_RING(3); + OUT_RING(DI_SRC_SEL_AUTO_INDEX); + + ADVANCE_RING(); + COMMIT_RING(); +} + +static inline void +set_default_state(drm_radeon_private_t *dev_priv) +{ + int default_state_dw, i; + u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2; + u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2; + int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs; + int num_ps_threads, num_vs_threads, num_gs_threads, num_es_threads; + int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries; + RING_LOCALS; + + switch ((dev_priv->flags & RADEON_FAMILY_MASK)) { + case CHIP_R600: + num_ps_gprs = 192; + num_vs_gprs = 56; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 136; + num_vs_threads = 48; + num_gs_threads = 4; + num_es_threads = 4; + num_ps_stack_entries = 128; + num_vs_stack_entries = 128; + num_gs_stack_entries = 0; + num_es_stack_entries = 0; + break; + case CHIP_RV630: + case CHIP_RV635: + num_ps_gprs = 84; + num_vs_gprs = 36; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 144; + num_vs_threads = 40; + num_gs_threads = 4; + num_es_threads = 4; + num_ps_stack_entries = 40; + num_vs_stack_entries = 40; + num_gs_stack_entries = 32; + num_es_stack_entries = 16; + break; + case CHIP_RV610: + case CHIP_RV620: + case CHIP_RS780: + /*case CHIP_RS880:*/ + default: + num_ps_gprs = 84; + num_vs_gprs = 36; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 136; + num_vs_threads = 48; + num_gs_threads = 4; + num_es_threads = 4; + num_ps_stack_entries = 40; + num_vs_stack_entries = 40; + num_gs_stack_entries = 32; + num_es_stack_entries = 16; + break; + case CHIP_RV670: + num_ps_gprs = 144; + num_vs_gprs = 40; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 136; + num_vs_threads = 48; + num_gs_threads = 4; + num_es_threads = 4; + num_ps_stack_entries = 40; + num_vs_stack_entries = 40; + num_gs_stack_entries = 32; + num_es_stack_entries = 16; + break; + case CHIP_RV770: + num_ps_gprs = 192; + num_vs_gprs = 56; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 188; + num_vs_threads = 60; + num_gs_threads = 0; + num_es_threads = 0; + num_ps_stack_entries = 256; + num_vs_stack_entries = 256; + num_gs_stack_entries = 0; + num_es_stack_entries = 0; + break; + case CHIP_RV730: + case CHIP_RV740: + num_ps_gprs = 84; + num_vs_gprs = 36; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 188; + num_vs_threads = 60; + num_gs_threads = 0; + num_es_threads = 0; + num_ps_stack_entries = 128; + num_vs_stack_entries = 128; + num_gs_stack_entries = 0; + num_es_stack_entries = 0; + break; + case CHIP_RV710: + num_ps_gprs = 192; + num_vs_gprs = 56; + num_temp_gprs = 4; + num_gs_gprs = 0; + num_es_gprs = 0; + num_ps_threads = 144; + num_vs_threads = 48; + num_gs_threads = 0; + num_es_threads = 0; + num_ps_stack_entries = 128; + num_vs_stack_entries = 128; + num_gs_stack_entries = 0; + num_es_stack_entries = 0; + break; + } + + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || + /*((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) ||*/ + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) + sq_config = 0; + else + sq_config = R600_VC_ENABLE; + + sq_config |= (R600_DX9_CONSTS | + R600_ALU_INST_PREFER_VECTOR | + R600_PS_PRIO(0) | + R600_VS_PRIO(1) | + R600_GS_PRIO(2) | + R600_ES_PRIO(3)); + + sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(num_ps_gprs) | + R600_NUM_VS_GPRS(num_vs_gprs) | + R600_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs)); + sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(num_gs_gprs) | + R600_NUM_ES_GPRS(num_es_gprs)); + sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(num_ps_threads) | + R600_NUM_VS_THREADS(num_vs_threads) | + R600_NUM_GS_THREADS(num_gs_threads) | + R600_NUM_ES_THREADS(num_es_threads)); + sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(num_ps_stack_entries) | + R600_NUM_VS_STACK_ENTRIES(num_vs_stack_entries)); + sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(num_gs_stack_entries) | + R600_NUM_ES_STACK_ENTRIES(num_es_stack_entries)); + + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) { + default_state_dw = sizeof(r7xx_default_state) / 4; + BEGIN_RING(default_state_dw + 10); + for (i = 0; i < default_state_dw; i++) + OUT_RING(r7xx_default_state[i]); + } else { + default_state_dw = sizeof(r6xx_default_state) / 4; + BEGIN_RING(default_state_dw + 10); + for (i = 0; i < default_state_dw; i++) + OUT_RING(r6xx_default_state[i]); + } + OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0)); + OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT); + /* SQ config */ + OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 6)); + OUT_RING((R600_SQ_CONFIG - R600_SET_CONFIG_REG_OFFSET) >> 2); + OUT_RING(sq_config); + OUT_RING(sq_gpr_resource_mgmt_1); + OUT_RING(sq_gpr_resource_mgmt_2); + OUT_RING(sq_thread_resource_mgmt); + OUT_RING(sq_stack_resource_mgmt_1); + OUT_RING(sq_stack_resource_mgmt_2); + ADVANCE_RING(); +} + +static inline uint32_t i2f(uint32_t input) +{ + u32 result, i, exponent, fraction; + + if ((input & 0x3fff) == 0) + result = 0; /* 0 is a special case */ + else { + exponent = 140; /* exponent biased by 127; */ + fraction = (input & 0x3fff) << 10; /* cheat and only + handle numbers below 2^^15 */ + for (i = 0; i < 14; i++) { + if (fraction & 0x800000) + break; + else { + fraction = fraction << 1; /* keep + shifting left until top bit = 1 */ + exponent = exponent -1; + } + } + result = exponent << 23 | (fraction & 0x7fffff); /* mask + off top bit; assumed 1 */ + } + return result; +} + +int +r600_prepare_blit_copy(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG("\n"); + + dev_priv->blit_vb = radeon_freelist_get(dev); + if (!dev_priv->blit_vb) { + DRM_ERROR("Unable to allocate vertex buffer for blit\n"); + return -EAGAIN; + } + + set_default_state(dev_priv); + set_shaders(dev); + + return 0; +} + +void +r600_done_blit_copy(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + DRM_DEBUG("\n"); + + BEGIN_RING(5); + OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0)); + OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT); + /* wait for 3D idle clean */ + OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); + OUT_RING((R600_WAIT_UNTIL - R600_SET_CONFIG_REG_OFFSET) >> 2); + OUT_RING(RADEON_WAIT_3D_IDLE | RADEON_WAIT_3D_IDLECLEAN); + + ADVANCE_RING(); + COMMIT_RING(); + + dev_priv->blit_vb->used = 0; + radeon_cp_discard_buffer(dev, dev_priv->blit_vb); +} + +void +r600_blit_copy(struct drm_device *dev, + uint64_t src_gpu_addr, uint64_t dst_gpu_addr, + int size_bytes) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + int max_bytes; + u64 vb_addr; + u32 *vb; + + vb = (u32 *) ((char *)dev->agp_buffer_map->handle + + dev_priv->blit_vb->offset + dev_priv->blit_vb->used); + + if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) { + max_bytes = 8192; + + while (size_bytes) { + int cur_size = size_bytes; + int src_x = src_gpu_addr & 255; + int dst_x = dst_gpu_addr & 255; + int h = 1; + src_gpu_addr = src_gpu_addr & ~255; + dst_gpu_addr = dst_gpu_addr & ~255; + + if (!src_x && !dst_x) { + h = (cur_size / max_bytes); + if (h > 8192) + h = 8192; + if (h == 0) + h = 1; + else + cur_size = max_bytes; + } else { + if (cur_size > max_bytes) + cur_size = max_bytes; + if (cur_size > (max_bytes - dst_x)) + cur_size = (max_bytes - dst_x); + if (cur_size > (max_bytes - src_x)) + cur_size = (max_bytes - src_x); + } + + if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) { + dev_priv->blit_vb->used = 0; + radeon_cp_discard_buffer(dev, dev_priv->blit_vb); + dev_priv->blit_vb = radeon_freelist_get(dev); + if (!dev_priv->blit_vb) + return; + set_shaders(dev); + vb = (u32 *) ((char *)dev->agp_buffer_map->handle + + dev_priv->blit_vb->offset + dev_priv->blit_vb->used); + } + + vb[0] = i2f(dst_x); + vb[1] = 0; + vb[2] = i2f(src_x); + vb[3] = 0; + + vb[4] = i2f(dst_x); + vb[5] = i2f(h); + vb[6] = i2f(src_x); + vb[7] = i2f(h); + + vb[8] = i2f(dst_x + cur_size); + vb[9] = i2f(h); + vb[10] = i2f(src_x + cur_size); + vb[11] = i2f(h); + + /* src */ + set_tex_resource(dev_priv, FMT_8, + src_x + cur_size, h, src_x + cur_size, + src_gpu_addr); + + cp_set_surface_sync(dev_priv, + R600_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr); + + /* dst */ + set_render_target(dev_priv, COLOR_8, + dst_x + cur_size, h, + dst_gpu_addr); + + /* scissors */ + set_scissors(dev_priv, dst_x, 0, dst_x + cur_size, h); + + /* Vertex buffer setup */ + vb_addr = dev_priv->gart_buffers_offset + + dev_priv->blit_vb->offset + + dev_priv->blit_vb->used; + set_vtx_resource(dev_priv, vb_addr); + + /* draw */ + draw_auto(dev_priv); + + cp_set_surface_sync(dev_priv, + R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, + cur_size * h, dst_gpu_addr); + + vb += 12; + dev_priv->blit_vb->used += 12 * 4; + + src_gpu_addr += cur_size * h; + dst_gpu_addr += cur_size * h; + size_bytes -= cur_size * h; + } + } else { + max_bytes = 8192 * 4; + + while (size_bytes) { + int cur_size = size_bytes; + int src_x = (src_gpu_addr & 255); + int dst_x = (dst_gpu_addr & 255); + int h = 1; + src_gpu_addr = src_gpu_addr & ~255; + dst_gpu_addr = dst_gpu_addr & ~255; + + if (!src_x && !dst_x) { + h = (cur_size / max_bytes); + if (h > 8192) + h = 8192; + if (h == 0) + h = 1; + else + cur_size = max_bytes; + } else { + if (cur_size > max_bytes) + cur_size = max_bytes; + if (cur_size > (max_bytes - dst_x)) + cur_size = (max_bytes - dst_x); + if (cur_size > (max_bytes - src_x)) + cur_size = (max_bytes - src_x); + } + + if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) { + dev_priv->blit_vb->used = 0; + radeon_cp_discard_buffer(dev, dev_priv->blit_vb); + dev_priv->blit_vb = radeon_freelist_get(dev); + if (!dev_priv->blit_vb) + return; + set_shaders(dev); + vb = (u32 *) ((char *)dev->agp_buffer_map->handle + + dev_priv->blit_vb->offset + dev_priv->blit_vb->used); + } + + vb[0] = i2f(dst_x / 4); + vb[1] = 0; + vb[2] = i2f(src_x / 4); + vb[3] = 0; + + vb[4] = i2f(dst_x / 4); + vb[5] = i2f(h); + vb[6] = i2f(src_x / 4); + vb[7] = i2f(h); + + vb[8] = i2f((dst_x + cur_size) / 4); + vb[9] = i2f(h); + vb[10] = i2f((src_x + cur_size) / 4); + vb[11] = i2f(h); + + /* src */ + set_tex_resource(dev_priv, FMT_8_8_8_8, + (src_x + cur_size) / 4, + h, (src_x + cur_size) / 4, + src_gpu_addr); + + cp_set_surface_sync(dev_priv, + R600_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr); + + /* dst */ + set_render_target(dev_priv, COLOR_8_8_8_8, + (dst_x + cur_size) / 4, h, + dst_gpu_addr); + + /* scissors */ + set_scissors(dev_priv, (dst_x / 4), 0, (dst_x + cur_size / 4), h); + + /* Vertex buffer setup */ + vb_addr = dev_priv->gart_buffers_offset + + dev_priv->blit_vb->offset + + dev_priv->blit_vb->used; + set_vtx_resource(dev_priv, vb_addr); + + /* draw */ + draw_auto(dev_priv); + + cp_set_surface_sync(dev_priv, + R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, + cur_size * h, dst_gpu_addr); + + vb += 12; + dev_priv->blit_vb->used += 12 * 4; + + src_gpu_addr += cur_size * h; + dst_gpu_addr += cur_size * h; + size_bytes -= cur_size * h; + } + } +} + +void +r600_blit_swap(struct drm_device *dev, + uint64_t src_gpu_addr, uint64_t dst_gpu_addr, + int sx, int sy, int dx, int dy, + int w, int h, int src_pitch, int dst_pitch, int cpp) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + int cb_format, tex_format; + u64 vb_addr; + u32 *vb; + + vb = (u32 *) ((char *)dev->agp_buffer_map->handle + + dev_priv->blit_vb->offset + dev_priv->blit_vb->used); + + if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) { + dev_priv->blit_vb->used = 0; + radeon_cp_discard_buffer(dev, dev_priv->blit_vb); + dev_priv->blit_vb = radeon_freelist_get(dev); + if (!dev_priv->blit_vb) + return; + set_shaders(dev); + vb = (u32 *) ((char *)dev->agp_buffer_map->handle + + dev_priv->blit_vb->offset + dev_priv->blit_vb->used); + } + + if (cpp == 4) { + cb_format = COLOR_8_8_8_8; + tex_format = FMT_8_8_8_8; + } else if (cpp == 2) { + cb_format = COLOR_5_6_5; + tex_format = FMT_5_6_5; + } else { + cb_format = COLOR_8; + tex_format = FMT_8; + } + + vb[0] = i2f(dx); + vb[1] = i2f(dy); + vb[2] = i2f(sx); + vb[3] = i2f(sy); + + vb[4] = i2f(dx); + vb[5] = i2f(dy + h); + vb[6] = i2f(sx); + vb[7] = i2f(sy + h); + + vb[8] = i2f(dx + w); + vb[9] = i2f(dy + h); + vb[10] = i2f(sx + w); + vb[11] = i2f(sy + h); + + /* src */ + set_tex_resource(dev_priv, tex_format, + src_pitch / cpp, + sy + h, src_pitch / cpp, + src_gpu_addr); + + cp_set_surface_sync(dev_priv, + R600_TC_ACTION_ENA, (src_pitch * (sy + h)), src_gpu_addr); + + /* dst */ + set_render_target(dev_priv, cb_format, + dst_pitch / cpp, dy + h, + dst_gpu_addr); + + /* scissors */ + set_scissors(dev_priv, dx, dy, dx + w, dy + h); + + /* Vertex buffer setup */ + vb_addr = dev_priv->gart_buffers_offset + + dev_priv->blit_vb->offset + + dev_priv->blit_vb->used; + set_vtx_resource(dev_priv, vb_addr); + + /* draw */ + draw_auto(dev_priv); + + cp_set_surface_sync(dev_priv, + R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, + dst_pitch * (dy + h), dst_gpu_addr); + + dev_priv->blit_vb->used += 12 * 4; +} diff --git a/sys/dev/drm/radeon_cs.c b/sys/dev/drm/radeon_cs.c new file mode 100644 index 00000000000..b523126b947 --- /dev/null +++ b/sys/dev/drm/radeon_cs.c @@ -0,0 +1,856 @@ +/*- + * Copyright 2008 Jerome Glisse. + * All Rights Reserved. + * + * 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 (including the next + * paragraph) 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 + * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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: + * Jerome Glisse + */ + +#include +__FBSDID("$FreeBSD$"); +#include "dev/drm/drmP.h" +#include "dev/drm/radeon_drm.h" +#include "dev/drm/radeon_drv.h" + +/* regs */ +#define AVIVO_D1MODE_VLINE_START_END 0x6538 +#define AVIVO_D2MODE_VLINE_START_END 0x6d38 +#define R600_CP_COHER_BASE 0x85f8 +#define R600_DB_DEPTH_BASE 0x2800c +#define R600_CB_COLOR0_BASE 0x28040 +#define R600_CB_COLOR1_BASE 0x28044 +#define R600_CB_COLOR2_BASE 0x28048 +#define R600_CB_COLOR3_BASE 0x2804c +#define R600_CB_COLOR4_BASE 0x28050 +#define R600_CB_COLOR5_BASE 0x28054 +#define R600_CB_COLOR6_BASE 0x28058 +#define R600_CB_COLOR7_BASE 0x2805c +#define R600_SQ_PGM_START_FS 0x28894 +#define R600_SQ_PGM_START_ES 0x28880 +#define R600_SQ_PGM_START_VS 0x28858 +#define R600_SQ_PGM_START_GS 0x2886c +#define R600_SQ_PGM_START_PS 0x28840 +#define R600_VGT_DMA_BASE 0x287e8 +#define R600_VGT_DMA_BASE_HI 0x287e4 +#define R600_VGT_STRMOUT_BASE_OFFSET_0 0x28b10 +#define R600_VGT_STRMOUT_BASE_OFFSET_1 0x28b14 +#define R600_VGT_STRMOUT_BASE_OFFSET_2 0x28b18 +#define R600_VGT_STRMOUT_BASE_OFFSET_3 0x28b1c +#define R600_VGT_STRMOUT_BASE_OFFSET_HI_0 0x28b44 +#define R600_VGT_STRMOUT_BASE_OFFSET_HI_1 0x28b48 +#define R600_VGT_STRMOUT_BASE_OFFSET_HI_2 0x28b4c +#define R600_VGT_STRMOUT_BASE_OFFSET_HI_3 0x28b50 +#define R600_VGT_STRMOUT_BUFFER_BASE_0 0x28ad8 +#define R600_VGT_STRMOUT_BUFFER_BASE_1 0x28ae8 +#define R600_VGT_STRMOUT_BUFFER_BASE_2 0x28af8 +#define R600_VGT_STRMOUT_BUFFER_BASE_3 0x28b08 +#define R600_VGT_STRMOUT_BUFFER_OFFSET_0 0x28adc +#define R600_VGT_STRMOUT_BUFFER_OFFSET_1 0x28aec +#define R600_VGT_STRMOUT_BUFFER_OFFSET_2 0x28afc +#define R600_VGT_STRMOUT_BUFFER_OFFSET_3 0x28b0c + +/* resource type */ +#define R600_SQ_TEX_VTX_INVALID_TEXTURE 0x0 +#define R600_SQ_TEX_VTX_INVALID_BUFFER 0x1 +#define R600_SQ_TEX_VTX_VALID_TEXTURE 0x2 +#define R600_SQ_TEX_VTX_VALID_BUFFER 0x3 + +/* packet 3 type offsets */ +#define R600_SET_CONFIG_REG_OFFSET 0x00008000 +#define R600_SET_CONFIG_REG_END 0x0000ac00 +#define R600_SET_CONTEXT_REG_OFFSET 0x00028000 +#define R600_SET_CONTEXT_REG_END 0x00029000 +#define R600_SET_ALU_CONST_OFFSET 0x00030000 +#define R600_SET_ALU_CONST_END 0x00032000 +#define R600_SET_RESOURCE_OFFSET 0x00038000 +#define R600_SET_RESOURCE_END 0x0003c000 +#define R600_SET_SAMPLER_OFFSET 0x0003c000 +#define R600_SET_SAMPLER_END 0x0003cff0 +#define R600_SET_CTL_CONST_OFFSET 0x0003cff0 +#define R600_SET_CTL_CONST_END 0x0003e200 +#define R600_SET_LOOP_CONST_OFFSET 0x0003e200 +#define R600_SET_LOOP_CONST_END 0x0003e380 +#define R600_SET_BOOL_CONST_OFFSET 0x0003e380 +#define R600_SET_BOOL_CONST_END 0x00040000 + +/* Packet 3 types */ +#define R600_IT_INDIRECT_BUFFER_END 0x00001700 +#define R600_IT_SET_PREDICATION 0x00002000 +#define R600_IT_REG_RMW 0x00002100 +#define R600_IT_COND_EXEC 0x00002200 +#define R600_IT_PRED_EXEC 0x00002300 +#define R600_IT_START_3D_CMDBUF 0x00002400 +#define R600_IT_DRAW_INDEX_2 0x00002700 +#define R600_IT_CONTEXT_CONTROL 0x00002800 +#define R600_IT_DRAW_INDEX_IMMD_BE 0x00002900 +#define R600_IT_INDEX_TYPE 0x00002A00 +#define R600_IT_DRAW_INDEX 0x00002B00 +#define R600_IT_DRAW_INDEX_AUTO 0x00002D00 +#define R600_IT_DRAW_INDEX_IMMD 0x00002E00 +#define R600_IT_NUM_INSTANCES 0x00002F00 +#define R600_IT_STRMOUT_BUFFER_UPDATE 0x00003400 +#define R600_IT_INDIRECT_BUFFER_MP 0x00003800 +#define R600_IT_MEM_SEMAPHORE 0x00003900 +#define R600_IT_MPEG_INDEX 0x00003A00 +#define R600_IT_WAIT_REG_MEM 0x00003C00 +#define R600_IT_MEM_WRITE 0x00003D00 +#define R600_IT_INDIRECT_BUFFER 0x00003200 +#define R600_IT_CP_INTERRUPT 0x00004000 +#define R600_IT_SURFACE_SYNC 0x00004300 +#define R600_IT_ME_INITIALIZE 0x00004400 +#define R600_IT_COND_WRITE 0x00004500 +#define R600_IT_EVENT_WRITE 0x00004600 +#define R600_IT_EVENT_WRITE_EOP 0x00004700 +#define R600_IT_ONE_REG_WRITE 0x00005700 +#define R600_IT_SET_CONFIG_REG 0x00006800 +#define R600_IT_SET_CONTEXT_REG 0x00006900 +#define R600_IT_SET_ALU_CONST 0x00006A00 +#define R600_IT_SET_BOOL_CONST 0x00006B00 +#define R600_IT_SET_LOOP_CONST 0x00006C00 +#define R600_IT_SET_RESOURCE 0x00006D00 +#define R600_IT_SET_SAMPLER 0x00006E00 +#define R600_IT_SET_CTL_CONST 0x00006F00 +#define R600_IT_SURFACE_BASE_UPDATE 0x00007300 + +int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) +{ + struct drm_radeon_cs_parser parser; + struct drm_radeon_private *dev_priv = dev->dev_private; + struct drm_radeon_cs *cs = data; + uint32_t cs_id; + struct drm_radeon_cs_chunk __user **chunk_ptr = NULL; + uint64_t *chunk_array; + uint64_t *chunk_array_ptr; + long size; + int r, i; + + mtx_lock(&dev_priv->cs.cs_mutex); + /* set command stream id to 0 which is fake id */ + cs_id = 0; + cs->cs_id = cs_id; + + if (dev_priv == NULL) { + DRM_ERROR("called with no initialization\n"); + mtx_unlock(&dev_priv->cs.cs_mutex); + return -EINVAL; + } + if (!cs->num_chunks) { + mtx_unlock(&dev_priv->cs.cs_mutex); + return 0; + } + + + chunk_array = drm_calloc(cs->num_chunks, sizeof(uint64_t), DRM_MEM_DRIVER); + if (!chunk_array) { + mtx_unlock(&dev_priv->cs.cs_mutex); + return -ENOMEM; + } + + chunk_array_ptr = (uint64_t *)(unsigned long)(cs->chunks); + + if (DRM_COPY_FROM_USER(chunk_array, chunk_array_ptr, sizeof(uint64_t)*cs->num_chunks)) { + r = -EFAULT; + goto out; + } + + parser.dev = dev; + parser.file_priv = fpriv; + parser.reloc_index = -1; + parser.ib_index = -1; + parser.num_chunks = cs->num_chunks; + /* copy out the chunk headers */ + parser.chunks = drm_calloc(parser.num_chunks, sizeof(struct drm_radeon_kernel_chunk), DRM_MEM_DRIVER); + if (!parser.chunks) { + r = -ENOMEM; + goto out; + } + + for (i = 0; i < parser.num_chunks; i++) { + struct drm_radeon_cs_chunk user_chunk; + + chunk_ptr = (void __user *)(unsigned long)chunk_array[i]; + + if (DRM_COPY_FROM_USER(&user_chunk, chunk_ptr, sizeof(struct drm_radeon_cs_chunk))){ + r = -EFAULT; + goto out; + } + parser.chunks[i].chunk_id = user_chunk.chunk_id; + + if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) + parser.reloc_index = i; + + if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_IB) + parser.ib_index = i; + + if (parser.chunks[i].chunk_id == RADEON_CHUNK_ID_OLD) { + parser.ib_index = i; + parser.reloc_index = -1; + } + + parser.chunks[i].length_dw = user_chunk.length_dw; + parser.chunks[i].chunk_data = (uint32_t *)(unsigned long)user_chunk.chunk_data; + + parser.chunks[i].kdata = NULL; + size = parser.chunks[i].length_dw * sizeof(uint32_t); + + switch(parser.chunks[i].chunk_id) { + case RADEON_CHUNK_ID_IB: + case RADEON_CHUNK_ID_OLD: + if (size == 0) { + r = -EINVAL; + goto out; + } + case RADEON_CHUNK_ID_RELOCS: + if (size) { + parser.chunks[i].kdata = drm_alloc(size, DRM_MEM_DRIVER); + if (!parser.chunks[i].kdata) { + r = -ENOMEM; + goto out; + } + + if (DRM_COPY_FROM_USER(parser.chunks[i].kdata, parser.chunks[i].chunk_data, size)) { + r = -EFAULT; + goto out; + } + } else + parser.chunks[i].kdata = NULL; + break; + default: + break; + } + DRM_DEBUG("chunk %d %d %d %p\n", i, parser.chunks[i].chunk_id, parser.chunks[i].length_dw, + parser.chunks[i].chunk_data); + } + + if (parser.chunks[parser.ib_index].length_dw > (16 * 1024)) { + DRM_ERROR("cs->dwords too big: %d\n", parser.chunks[parser.ib_index].length_dw); + r = -EINVAL; + goto out; + } + + /* get ib */ + r = dev_priv->cs.ib_get(&parser); + if (r) { + DRM_ERROR("ib_get failed\n"); + goto out; + } + + /* now parse command stream */ + r = dev_priv->cs.parse(&parser); + if (r) { + goto out; + } + +out: + dev_priv->cs.ib_free(&parser, r); + + /* emit cs id sequence */ + dev_priv->cs.id_emit(&parser, &cs_id); + + cs->cs_id = cs_id; + + mtx_unlock(&dev_priv->cs.cs_mutex); + + for (i = 0; i < parser.num_chunks; i++) { + if (parser.chunks[i].kdata) + drm_free(parser.chunks[i].kdata, parser.chunks[i].length_dw * sizeof(uint32_t), DRM_MEM_DRIVER); + } + + drm_free(parser.chunks, sizeof(struct drm_radeon_kernel_chunk)*parser.num_chunks, DRM_MEM_DRIVER); + drm_free(chunk_array, sizeof(uint64_t)*parser.num_chunks, DRM_MEM_DRIVER); + + return r; +} + +/* for non-mm */ +static int r600_nomm_relocate(struct drm_radeon_cs_parser *parser, uint32_t *reloc, uint64_t *offset) +{ + struct drm_device *dev = parser->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_radeon_kernel_chunk *reloc_chunk = &parser->chunks[parser->reloc_index]; + uint32_t offset_dw = reloc[1]; + + //DRM_INFO("reloc: 0x%08x 0x%08x\n", reloc[0], reloc[1]); + //DRM_INFO("length: %d\n", reloc_chunk->length_dw); + + if (!reloc_chunk->kdata) + return -EINVAL; + + if (offset_dw > reloc_chunk->length_dw) { + DRM_ERROR("Offset larger than chunk 0x%x %d\n", offset_dw, reloc_chunk->length_dw); + return -EINVAL; + } + + /* 40 bit addr */ + *offset = reloc_chunk->kdata[offset_dw + 3]; + *offset <<= 32; + *offset |= reloc_chunk->kdata[offset_dw + 0]; + + //DRM_INFO("offset 0x%lx\n", *offset); + + if (!radeon_check_offset(dev_priv, *offset)) { + DRM_ERROR("bad offset! 0x%lx\n", (unsigned long)*offset); + return -EINVAL; + } + + return 0; +} + +static inline int r600_cs_packet0(struct drm_radeon_cs_parser *parser, uint32_t *offset_dw_p) +{ + uint32_t hdr, num_dw, reg; + int count_dw = 1; + int ret = 0; + uint32_t offset_dw = *offset_dw_p; + int incr = 2; + + hdr = parser->chunks[parser->ib_index].kdata[offset_dw]; + num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2; + reg = (hdr & 0xffff) << 2; + + while (count_dw < num_dw) { + switch (reg) { + case AVIVO_D1MODE_VLINE_START_END: + case AVIVO_D2MODE_VLINE_START_END: + break; + default: + ret = -EINVAL; + DRM_ERROR("bad packet 0 reg: 0x%08x\n", reg); + break; + } + if (ret) + break; + count_dw++; + reg += 4; + } + *offset_dw_p += incr; + return ret; +} + +static inline int r600_cs_packet3(struct drm_radeon_cs_parser *parser, uint32_t *offset_dw_p) +{ + struct drm_device *dev = parser->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + uint32_t hdr, num_dw, start_reg, end_reg, reg; + uint32_t *reloc; + uint64_t offset; + int ret = 0; + uint32_t offset_dw = *offset_dw_p; + int incr = 2; + int i; + struct drm_radeon_kernel_chunk *ib_chunk; + + ib_chunk = &parser->chunks[parser->ib_index]; + + hdr = ib_chunk->kdata[offset_dw]; + num_dw = ((hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16) + 2; + + /* just the ones we use for now, add more later */ + switch (hdr & 0xff00) { + case R600_IT_START_3D_CMDBUF: + //DRM_INFO("R600_IT_START_3D_CMDBUF\n"); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) + ret = -EINVAL; + if (num_dw != 2) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad START_3D\n"); + break; + case R600_IT_CONTEXT_CONTROL: + //DRM_INFO("R600_IT_CONTEXT_CONTROL\n"); + if (num_dw != 3) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad CONTEXT_CONTROL\n"); + break; + case R600_IT_INDEX_TYPE: + case R600_IT_NUM_INSTANCES: + //DRM_INFO("R600_IT_INDEX_TYPE/R600_IT_NUM_INSTANCES\n"); + if (num_dw != 2) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES\n"); + break; + case R600_IT_DRAW_INDEX: + //DRM_INFO("R600_IT_DRAW_INDEX\n"); + if (num_dw != 5) { + ret = -EINVAL; + DRM_ERROR("bad DRAW_INDEX\n"); + break; + } + reloc = ib_chunk->kdata + offset_dw + num_dw; + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) { + DRM_ERROR("bad DRAW_INDEX\n"); + break; + } + ib_chunk->kdata[offset_dw + 1] += (offset & 0xffffffff); + ib_chunk->kdata[offset_dw + 2] += (upper_32_bits(offset) & 0xff); + break; + case R600_IT_DRAW_INDEX_AUTO: + //DRM_INFO("R600_IT_DRAW_INDEX_AUTO\n"); + if (num_dw != 3) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad DRAW_INDEX_AUTO\n"); + break; + case R600_IT_DRAW_INDEX_IMMD_BE: + case R600_IT_DRAW_INDEX_IMMD: + //DRM_INFO("R600_IT_DRAW_INDEX_IMMD\n"); + if (num_dw < 4) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad DRAW_INDEX_IMMD\n"); + break; + case R600_IT_WAIT_REG_MEM: + //DRM_INFO("R600_IT_WAIT_REG_MEM\n"); + if (num_dw != 7) + ret = -EINVAL; + /* bit 4 is reg (0) or mem (1) */ + if (ib_chunk->kdata[offset_dw + 1] & 0x10) { + reloc = ib_chunk->kdata + offset_dw + num_dw; + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) { + DRM_ERROR("bad WAIT_REG_MEM\n"); + break; + } + ib_chunk->kdata[offset_dw + 2] += (offset & 0xffffffff); + ib_chunk->kdata[offset_dw + 3] += (upper_32_bits(offset) & 0xff); + } + if (ret) + DRM_ERROR("bad WAIT_REG_MEM\n"); + break; + case R600_IT_SURFACE_SYNC: + //DRM_INFO("R600_IT_SURFACE_SYNC\n"); + if (num_dw != 5) + ret = -EINVAL; + /* 0xffffffff/0x0 is flush all cache flag */ + else if ((ib_chunk->kdata[offset_dw + 2] == 0xffffffff) && + (ib_chunk->kdata[offset_dw + 3] == 0)) + ret = 0; + else { + reloc = ib_chunk->kdata + offset_dw + num_dw; + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) { + DRM_ERROR("bad SURFACE_SYNC\n"); + break; + } + ib_chunk->kdata[offset_dw + 3] += ((offset >> 8) & 0xffffffff); + } + break; + case R600_IT_EVENT_WRITE: + //DRM_INFO("R600_IT_EVENT_WRITE\n"); + if ((num_dw != 4) && (num_dw != 2)) + ret = -EINVAL; + if (num_dw > 2) { + reloc = ib_chunk->kdata + offset_dw + num_dw; + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) { + DRM_ERROR("bad EVENT_WRITE\n"); + break; + } + ib_chunk->kdata[offset_dw + 2] += (offset & 0xffffffff); + ib_chunk->kdata[offset_dw + 3] += (upper_32_bits(offset) & 0xff); + } + if (ret) + DRM_ERROR("bad EVENT_WRITE\n"); + break; + case R600_IT_EVENT_WRITE_EOP: + //DRM_INFO("R600_IT_EVENT_WRITE_EOP\n"); + if (num_dw != 6) { + ret = -EINVAL; + DRM_ERROR("bad EVENT_WRITE_EOP\n"); + break; + } + reloc = ib_chunk->kdata + offset_dw + num_dw; + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) { + DRM_ERROR("bad EVENT_WRITE_EOP\n"); + break; + } + ib_chunk->kdata[offset_dw + 2] += (offset & 0xffffffff); + ib_chunk->kdata[offset_dw + 3] += (upper_32_bits(offset) & 0xff); + break; + case R600_IT_SET_CONFIG_REG: + //DRM_INFO("R600_IT_SET_CONFIG_REG\n"); + start_reg = (ib_chunk->kdata[offset_dw + 1] << 2) + R600_SET_CONFIG_REG_OFFSET; + end_reg = 4 * (num_dw - 2) + start_reg - 4; + if ((start_reg < R600_SET_CONFIG_REG_OFFSET) || + (start_reg >= R600_SET_CONFIG_REG_END) || + (end_reg >= R600_SET_CONFIG_REG_END)) + ret = -EINVAL; + else { + for (i = 0; i < (num_dw - 2); i++) { + reg = start_reg + (4 * i); + switch (reg) { + case R600_CP_COHER_BASE: + /* use R600_IT_SURFACE_SYNC */ + ret = -EINVAL; + break; + default: + break; + } + if (ret) + break; + } + } + if (ret) + DRM_ERROR("bad SET_CONFIG_REG\n"); + break; + case R600_IT_SET_CONTEXT_REG: + //DRM_INFO("R600_IT_SET_CONTEXT_REG\n"); + start_reg = ib_chunk->kdata[offset_dw + 1] << 2; + start_reg += R600_SET_CONTEXT_REG_OFFSET; + end_reg = 4 * (num_dw - 2) + start_reg - 4; + if ((start_reg < R600_SET_CONTEXT_REG_OFFSET) || + (start_reg >= R600_SET_CONTEXT_REG_END) || + (end_reg >= R600_SET_CONTEXT_REG_END)) + ret = -EINVAL; + else { + for (i = 0; i < (num_dw - 2); i++) { + reg = start_reg + (4 * i); + switch (reg) { + case R600_DB_DEPTH_BASE: + case R600_CB_COLOR0_BASE: + case R600_CB_COLOR1_BASE: + case R600_CB_COLOR2_BASE: + case R600_CB_COLOR3_BASE: + case R600_CB_COLOR4_BASE: + case R600_CB_COLOR5_BASE: + case R600_CB_COLOR6_BASE: + case R600_CB_COLOR7_BASE: + case R600_SQ_PGM_START_FS: + case R600_SQ_PGM_START_ES: + case R600_SQ_PGM_START_VS: + case R600_SQ_PGM_START_GS: + case R600_SQ_PGM_START_PS: + //DRM_INFO("reg: 0x%08x\n", reg); + reloc = ib_chunk->kdata + offset_dw + num_dw + (i * 2); + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) { + DRM_ERROR("bad SET_CONTEXT_REG\n"); + break; + } + ib_chunk->kdata[offset_dw + 2 + i] += + ((offset >> 8) & 0xffffffff); + break; + case R600_VGT_DMA_BASE: + case R600_VGT_DMA_BASE_HI: + /* These should be handled by DRAW_INDEX packet 3 */ + case R600_VGT_STRMOUT_BASE_OFFSET_0: + case R600_VGT_STRMOUT_BASE_OFFSET_1: + case R600_VGT_STRMOUT_BASE_OFFSET_2: + case R600_VGT_STRMOUT_BASE_OFFSET_3: + case R600_VGT_STRMOUT_BASE_OFFSET_HI_0: + case R600_VGT_STRMOUT_BASE_OFFSET_HI_1: + case R600_VGT_STRMOUT_BASE_OFFSET_HI_2: + case R600_VGT_STRMOUT_BASE_OFFSET_HI_3: + case R600_VGT_STRMOUT_BUFFER_BASE_0: + case R600_VGT_STRMOUT_BUFFER_BASE_1: + case R600_VGT_STRMOUT_BUFFER_BASE_2: + case R600_VGT_STRMOUT_BUFFER_BASE_3: + case R600_VGT_STRMOUT_BUFFER_OFFSET_0: + case R600_VGT_STRMOUT_BUFFER_OFFSET_1: + case R600_VGT_STRMOUT_BUFFER_OFFSET_2: + case R600_VGT_STRMOUT_BUFFER_OFFSET_3: + /* These should be handled by STRMOUT_BUFFER packet 3 */ + DRM_ERROR("bad context reg: 0x%08x\n", reg); + ret = -EINVAL; + break; + default: + break; + } + if (ret) + break; + } + } + if (ret) + DRM_ERROR("bad SET_CONTEXT_REG\n"); + break; + case R600_IT_SET_RESOURCE: + //DRM_INFO("R600_IT_SET_RESOURCE\n"); + if ((num_dw - 2) % 7) + ret = -EINVAL; + start_reg = ib_chunk->kdata[offset_dw + 1] << 2; + start_reg += R600_SET_RESOURCE_OFFSET; + end_reg = 4 * (num_dw - 2) + start_reg - 4; + if ((start_reg < R600_SET_RESOURCE_OFFSET) || + (start_reg >= R600_SET_RESOURCE_END) || + (end_reg >= R600_SET_RESOURCE_END)) + ret = -EINVAL; + else { + for (i = 0; i < ((num_dw - 2) / 7); i++) { + switch ((ib_chunk->kdata[offset_dw + (i * 7) + 6 + 2] & 0xc0000000) >> 30) { + case R600_SQ_TEX_VTX_INVALID_TEXTURE: + case R600_SQ_TEX_VTX_INVALID_BUFFER: + default: + ret = -EINVAL; + break; + case R600_SQ_TEX_VTX_VALID_TEXTURE: + /* tex base */ + reloc = ib_chunk->kdata + offset_dw + num_dw + (i * 4); + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) + break; + ib_chunk->kdata[offset_dw + (i * 7) + 2 + 2] += + ((offset >> 8) & 0xffffffff); + /* tex mip base */ + reloc = ib_chunk->kdata + offset_dw + num_dw + (i * 4) + 2; + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) + break; + ib_chunk->kdata[offset_dw + (i * 7) + 3 + 2] += + ((offset >> 8) & 0xffffffff); + break; + case R600_SQ_TEX_VTX_VALID_BUFFER: + /* vtx base */ + reloc = ib_chunk->kdata + offset_dw + num_dw + (i * 2); + ret = dev_priv->cs.relocate(parser, reloc, &offset); + if (ret) + break; + ib_chunk->kdata[offset_dw + (i * 7) + 0 + 2] += (offset & 0xffffffff); + ib_chunk->kdata[offset_dw + (i * 7) + 2 + 2] += (upper_32_bits(offset) & 0xff); + break; + } + if (ret) + break; + } + } + if (ret) + DRM_ERROR("bad SET_RESOURCE\n"); + break; + case R600_IT_SET_ALU_CONST: + //DRM_INFO("R600_IT_SET_ALU_CONST\n"); + start_reg = ib_chunk->kdata[offset_dw + 1] << 2; + start_reg += R600_SET_ALU_CONST_OFFSET; + end_reg = 4 * (num_dw - 2) + start_reg - 4; + if ((start_reg < R600_SET_ALU_CONST_OFFSET) || + (start_reg >= R600_SET_ALU_CONST_END) || + (end_reg >= R600_SET_ALU_CONST_END)) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad SET_ALU_CONST\n"); + break; + case R600_IT_SET_BOOL_CONST: + //DRM_INFO("R600_IT_SET_BOOL_CONST\n"); + start_reg = ib_chunk->kdata[offset_dw + 1] << 2; + start_reg += R600_SET_BOOL_CONST_OFFSET; + end_reg = 4 * (num_dw - 2) + start_reg - 4; + if ((start_reg < R600_SET_BOOL_CONST_OFFSET) || + (start_reg >= R600_SET_BOOL_CONST_END) || + (end_reg >= R600_SET_BOOL_CONST_END)) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad SET_BOOL_CONST\n"); + break; + case R600_IT_SET_LOOP_CONST: + //DRM_INFO("R600_IT_SET_LOOP_CONST\n"); + start_reg = ib_chunk->kdata[offset_dw + 1] << 2; + start_reg += R600_SET_LOOP_CONST_OFFSET; + end_reg = 4 * (num_dw - 2) + start_reg - 4; + if ((start_reg < R600_SET_LOOP_CONST_OFFSET) || + (start_reg >= R600_SET_LOOP_CONST_END) || + (end_reg >= R600_SET_LOOP_CONST_END)) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad SET_LOOP_CONST\n"); + break; + case R600_IT_SET_CTL_CONST: + //DRM_INFO("R600_IT_SET_CTL_CONST\n"); + start_reg = ib_chunk->kdata[offset_dw + 1] << 2; + start_reg += R600_SET_CTL_CONST_OFFSET; + end_reg = 4 * (num_dw - 2) + start_reg - 4; + if ((start_reg < R600_SET_CTL_CONST_OFFSET) || + (start_reg >= R600_SET_CTL_CONST_END) || + (end_reg >= R600_SET_CTL_CONST_END)) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad SET_CTL_CONST\n"); + break; + case R600_IT_SET_SAMPLER: + //DRM_INFO("R600_IT_SET_SAMPLER\n"); + if ((num_dw - 2) % 3) + ret = -EINVAL; + start_reg = ib_chunk->kdata[offset_dw + 1] << 2; + start_reg += R600_SET_SAMPLER_OFFSET; + end_reg = 4 * (num_dw - 2) + start_reg - 4; + if ((start_reg < R600_SET_SAMPLER_OFFSET) || + (start_reg >= R600_SET_SAMPLER_END) || + (end_reg >= R600_SET_SAMPLER_END)) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad SET_SAMPLER\n"); + break; + case R600_IT_SURFACE_BASE_UPDATE: + //DRM_INFO("R600_IT_SURFACE_BASE_UPDATE\n"); + if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600)) + ret = -EINVAL; + if (num_dw != 2) + ret = -EINVAL; + if (ret) + DRM_ERROR("bad SURFACE_BASE_UPDATE\n"); + break; + case RADEON_CP_NOP: + //DRM_INFO("NOP: %d\n", ib_chunk->kdata[offset_dw + 1]); + break; + default: + DRM_ERROR("invalid packet 3 0x%08x\n", 0xff00); + ret = -EINVAL; + break; + } + + *offset_dw_p += incr; + return ret; +} + +static int r600_cs_parse(struct drm_radeon_cs_parser *parser) +{ + volatile int rb; + struct drm_radeon_kernel_chunk *ib_chunk; + /* scan the packet for various things */ + int count_dw = 0, size_dw; + int ret = 0; + + ib_chunk = &parser->chunks[parser->ib_index]; + size_dw = ib_chunk->length_dw; + + while (count_dw < size_dw && ret == 0) { + int hdr = ib_chunk->kdata[count_dw]; + int num_dw = (hdr & RADEON_CP_PACKET_COUNT_MASK) >> 16; + + switch (hdr & RADEON_CP_PACKET_MASK) { + case RADEON_CP_PACKET0: + ret = r600_cs_packet0(parser, &count_dw); + break; + case RADEON_CP_PACKET1: + ret = -EINVAL; + break; + case RADEON_CP_PACKET2: + DRM_DEBUG("Packet 2\n"); + num_dw += 1; + break; + case RADEON_CP_PACKET3: + ret = r600_cs_packet3(parser, &count_dw); + break; + } + + count_dw += num_dw; + } + + if (ret) + return ret; + + + /* copy the packet into the IB */ + memcpy(parser->ib, ib_chunk->kdata, ib_chunk->length_dw * sizeof(uint32_t)); + + /* read back last byte to flush WC buffers */ + rb = readl(((vm_offset_t)parser->ib + (ib_chunk->length_dw-1) * sizeof(uint32_t))); + + return 0; +} + +static uint32_t radeon_cs_id_get(struct drm_radeon_private *radeon) +{ + /* FIXME: protect with a spinlock */ + /* FIXME: check if wrap affect last reported wrap & sequence */ + radeon->cs.id_scnt = (radeon->cs.id_scnt + 1) & 0x00FFFFFF; + if (!radeon->cs.id_scnt) { + /* increment wrap counter */ + radeon->cs.id_wcnt += 0x01000000; + /* valid sequence counter start at 1 */ + radeon->cs.id_scnt = 1; + } + return (radeon->cs.id_scnt | radeon->cs.id_wcnt); +} + +static void r600_cs_id_emit(struct drm_radeon_cs_parser *parser, uint32_t *id) +{ + drm_radeon_private_t *dev_priv = parser->dev->dev_private; + RING_LOCALS; + + //dev_priv->irq_emitted = radeon_update_breadcrumb(parser->dev); + + *id = radeon_cs_id_get(dev_priv); + + /* SCRATCH 2 */ + BEGIN_RING(3); + R600_CLEAR_AGE(*id); + ADVANCE_RING(); + COMMIT_RING(); +} + +static uint32_t r600_cs_id_last_get(struct drm_device *dev) +{ + //drm_radeon_private_t *dev_priv = dev->dev_private; + + //return GET_R600_SCRATCH(dev_priv, 2); + return 0; +} + +static int r600_ib_get(struct drm_radeon_cs_parser *parser) +{ + struct drm_device *dev = parser->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_buf *buf; + + buf = radeon_freelist_get(dev); + if (!buf) { + dev_priv->cs_buf = NULL; + return -EBUSY; + } + buf->file_priv = parser->file_priv; + dev_priv->cs_buf = buf; + parser->ib = (void *)((vm_offset_t)dev->agp_buffer_map->handle + + buf->offset); + + return 0; +} + +static void r600_ib_free(struct drm_radeon_cs_parser *parser, int error) +{ + struct drm_device *dev = parser->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_buf *buf = dev_priv->cs_buf; + + if (buf) { + if (!error) + r600_cp_dispatch_indirect(dev, buf, 0, + parser->chunks[parser->ib_index].length_dw * sizeof(uint32_t)); + radeon_cp_discard_buffer(dev, buf); + COMMIT_RING(); + } +} + +int r600_cs_init(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + dev_priv->cs.ib_get = r600_ib_get; + dev_priv->cs.ib_free = r600_ib_free; + dev_priv->cs.id_emit = r600_cs_id_emit; + dev_priv->cs.id_last_get = r600_cs_id_last_get; + dev_priv->cs.parse = r600_cs_parse; + dev_priv->cs.relocate = r600_nomm_relocate; + return 0; +} -- 2.45.2