1/* 2 * Copyright (C) 2007 Arthur Huillet. 3 * 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial 16 * portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 */ 27 28/* 29 * Authors: 30 * Arthur Huillet <arthur.huillet AT free DOT fr> 31 */ 32 33#include "drmP.h" 34#include "drm.h" 35#include "nouveau_drm.h" 36#include "nouveau_drv.h" 37#include "nouveau_reg.h" 38 39/*TODO: add a "card_type" attribute*/ 40typedef struct{ 41 uint32_t oclass; /* object class for this software method */ 42 uint32_t mthd; /* method number */ 43 void (*method_code)(struct drm_device *dev, uint32_t oclass, uint32_t mthd); /* pointer to the function that does the work */ 44 } nouveau_software_method_t; 45 46 47 /* This function handles the NV04 setcontext software methods. 48One function for all because they are very similar.*/ 49static void nouveau_NV04_setcontext_sw_method(struct drm_device *dev, uint32_t oclass, uint32_t mthd) { 50 struct drm_nouveau_private *dev_priv = dev->dev_private; 51 uint32_t inst_loc = NV_READ(NV04_PGRAPH_CTX_SWITCH4) & 0xFFFF; 52 uint32_t value_to_set = 0, bit_to_set = 0; 53 54 switch ( oclass ) { 55 case 0x4a: 56 switch ( mthd ) { 57 case 0x188 : 58 case 0x18c : 59 bit_to_set = 0; 60 break; 61 case 0x198 : 62 bit_to_set = 1 << 24; /*PATCH_STATUS_VALID*/ 63 break; 64 case 0x2fc : 65 bit_to_set = NV_READ(NV04_PGRAPH_TRAPPED_DATA) << 15; /*PATCH_CONFIG = NV04_PGRAPH_TRAPPED_DATA*/ 66 break; 67 default : ; 68 }; 69 break; 70 case 0x5c: 71 switch ( mthd ) { 72 case 0x184: 73 bit_to_set = 1 << 13; /*USER_CLIP_ENABLE*/ 74 break; 75 case 0x188: 76 case 0x18c: 77 bit_to_set = 0; 78 break; 79 case 0x198: 80 bit_to_set = 1 << 24; /*PATCH_STATUS_VALID*/ 81 break; 82 case 0x2fc : 83 bit_to_set = NV_READ(NV04_PGRAPH_TRAPPED_DATA) << 15; /*PATCH_CONFIG = NV04_PGRAPH_TRAPPED_DATA*/ 84 break; 85 }; 86 break; 87 case 0x5f: 88 switch ( mthd ) { 89 case 0x184 : 90 bit_to_set = 1 << 12; /*CHROMA_KEY_ENABLE*/ 91 break; 92 case 0x188 : 93 bit_to_set = 1 << 13; /*USER_CLIP_ENABLE*/ 94 break; 95 case 0x18c : 96 case 0x190 : 97 bit_to_set = 0; 98 break; 99 case 0x19c : 100 bit_to_set = 1 << 24; /*PATCH_STATUS_VALID*/ 101 break; 102 case 0x2fc : 103 bit_to_set = NV_READ(NV04_PGRAPH_TRAPPED_DATA) << 15; /*PATCH_CONFIG = NV04_PGRAPH_TRAPPED_DATA*/ 104 break; 105 }; 106 break; 107 case 0x61: 108 switch ( mthd ) { 109 case 0x188 : 110 bit_to_set = 1 << 13; /*USER_CLIP_ENABLE*/ 111 break; 112 case 0x18c : 113 case 0x190 : 114 bit_to_set = 0; 115 break; 116 case 0x19c : 117 bit_to_set = 1 << 24; /*PATCH_STATUS_VALID*/ 118 break; 119 case 0x2fc : 120 bit_to_set = NV_READ(NV04_PGRAPH_TRAPPED_DATA) << 15; /*PATCH_CONFIG = NV04_PGRAPH_TRAPPED_DATA*/ 121 break; 122 }; 123 break; 124 case 0x77: 125 switch ( mthd ) { 126 case 0x198 : 127 bit_to_set = 1 << 24; /*PATCH_STATUS_VALID*/ 128 break; 129 case 0x304 : 130 bit_to_set = NV_READ(NV04_PGRAPH_TRAPPED_DATA) << 15; //PATCH_CONFIG 131 break; 132 }; 133 break; 134 default :; 135 }; 136 137 value_to_set = (NV_READ(0x00700000 | inst_loc << 4))| bit_to_set; 138 139 /*RAMIN*/ 140 nouveau_wait_for_idle(dev); 141 NV_WRITE(0x00700000 | inst_loc << 4, value_to_set); 142 143 /*DRM_DEBUG("CTX_SWITCH1 value is %#x\n", NV_READ(NV04_PGRAPH_CTX_SWITCH1));*/ 144 NV_WRITE(NV04_PGRAPH_CTX_SWITCH1, value_to_set); 145 146 /*DRM_DEBUG("CTX_CACHE1 + xxx value is %#x\n", NV_READ(NV04_PGRAPH_CTX_CACHE1 + (((NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7) << 2)));*/ 147 NV_WRITE(NV04_PGRAPH_CTX_CACHE1 + (((NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7) << 2), value_to_set); 148} 149 150 nouveau_software_method_t nouveau_sw_methods[] = { 151 /*NV04 context software methods*/ 152 { 0x4a, 0x188, nouveau_NV04_setcontext_sw_method }, 153 { 0x4a, 0x18c, nouveau_NV04_setcontext_sw_method }, 154 { 0x4a, 0x198, nouveau_NV04_setcontext_sw_method }, 155 { 0x4a, 0x2fc, nouveau_NV04_setcontext_sw_method }, 156 { 0x5c, 0x184, nouveau_NV04_setcontext_sw_method }, 157 { 0x5c, 0x188, nouveau_NV04_setcontext_sw_method }, 158 { 0x5c, 0x18c, nouveau_NV04_setcontext_sw_method }, 159 { 0x5c, 0x198, nouveau_NV04_setcontext_sw_method }, 160 { 0x5c, 0x2fc, nouveau_NV04_setcontext_sw_method }, 161 { 0x5f, 0x184, nouveau_NV04_setcontext_sw_method }, 162 { 0x5f, 0x188, nouveau_NV04_setcontext_sw_method }, 163 { 0x5f, 0x18c, nouveau_NV04_setcontext_sw_method }, 164 { 0x5f, 0x190, nouveau_NV04_setcontext_sw_method }, 165 { 0x5f, 0x19c, nouveau_NV04_setcontext_sw_method }, 166 { 0x5f, 0x2fc, nouveau_NV04_setcontext_sw_method }, 167 { 0x61, 0x188, nouveau_NV04_setcontext_sw_method }, 168 { 0x61, 0x18c, nouveau_NV04_setcontext_sw_method }, 169 { 0x61, 0x190, nouveau_NV04_setcontext_sw_method }, 170 { 0x61, 0x19c, nouveau_NV04_setcontext_sw_method }, 171 { 0x61, 0x2fc, nouveau_NV04_setcontext_sw_method }, 172 { 0x77, 0x198, nouveau_NV04_setcontext_sw_method }, 173 { 0x77, 0x304, nouveau_NV04_setcontext_sw_method }, 174 /*terminator*/ 175 { 0x0, 0x0, NULL, }, 176 }; 177 178 int nouveau_sw_method_execute(struct drm_device *dev, uint32_t oclass, uint32_t method) { 179 int i = 0; 180 while ( nouveau_sw_methods[ i ] . method_code != NULL ) 181 { 182 if ( nouveau_sw_methods[ i ] . oclass == oclass && nouveau_sw_methods[ i ] . mthd == method ) 183 { 184 nouveau_sw_methods[ i ] . method_code(dev, oclass, method); 185 return 0; 186 } 187 i ++; 188 } 189 190 return 1; 191 } 192