@@ -161,116 +161,6 @@ auxch_tx(struct drm_device *dev, int ch, u8 type, u32 addr, u8 *data, u8 size)
161
161
return ret ;
162
162
}
163
163
164
- static u32
165
- dp_link_bw_get (struct drm_device * dev , int or , int link )
166
- {
167
- u32 ctrl = nv_rd32 (dev , 0x614300 + (or * 0x800 ));
168
- if (!(ctrl & 0x000c0000 ))
169
- return 162000 ;
170
- return 270000 ;
171
- }
172
-
173
- static int
174
- dp_lane_count_get (struct drm_device * dev , int or , int link )
175
- {
176
- u32 ctrl = nv_rd32 (dev , NV50_SOR_DP_CTRL (or , link ));
177
- switch (ctrl & 0x000f0000 ) {
178
- case 0x00010000 : return 1 ;
179
- case 0x00030000 : return 2 ;
180
- default :
181
- return 4 ;
182
- }
183
- }
184
-
185
- void
186
- nouveau_dp_tu_update (struct drm_device * dev , int or , int link , u32 clk , u32 bpp )
187
- {
188
- const u32 symbol = 100000 ;
189
- int bestTU = 0 , bestVTUi = 0 , bestVTUf = 0 , bestVTUa = 0 ;
190
- int TU , VTUi , VTUf , VTUa ;
191
- u64 link_data_rate , link_ratio , unk ;
192
- u32 best_diff = 64 * symbol ;
193
- u32 link_nr , link_bw , r ;
194
-
195
- /* calculate packed data rate for each lane */
196
- link_nr = dp_lane_count_get (dev , or , link );
197
- link_data_rate = (clk * bpp / 8 ) / link_nr ;
198
-
199
- /* calculate ratio of packed data rate to link symbol rate */
200
- link_bw = dp_link_bw_get (dev , or , link );
201
- link_ratio = link_data_rate * symbol ;
202
- r = do_div (link_ratio , link_bw );
203
-
204
- for (TU = 64 ; TU >= 32 ; TU -- ) {
205
- /* calculate average number of valid symbols in each TU */
206
- u32 tu_valid = link_ratio * TU ;
207
- u32 calc , diff ;
208
-
209
- /* find a hw representation for the fraction.. */
210
- VTUi = tu_valid / symbol ;
211
- calc = VTUi * symbol ;
212
- diff = tu_valid - calc ;
213
- if (diff ) {
214
- if (diff >= (symbol / 2 )) {
215
- VTUf = symbol / (symbol - diff );
216
- if (symbol - (VTUf * diff ))
217
- VTUf ++ ;
218
-
219
- if (VTUf <= 15 ) {
220
- VTUa = 1 ;
221
- calc += symbol - (symbol / VTUf );
222
- } else {
223
- VTUa = 0 ;
224
- VTUf = 1 ;
225
- calc += symbol ;
226
- }
227
- } else {
228
- VTUa = 0 ;
229
- VTUf = min ((int )(symbol / diff ), 15 );
230
- calc += symbol / VTUf ;
231
- }
232
-
233
- diff = calc - tu_valid ;
234
- } else {
235
- /* no remainder, but the hw doesn't like the fractional
236
- * part to be zero. decrement the integer part and
237
- * have the fraction add a whole symbol back
238
- */
239
- VTUa = 0 ;
240
- VTUf = 1 ;
241
- VTUi -- ;
242
- }
243
-
244
- if (diff < best_diff ) {
245
- best_diff = diff ;
246
- bestTU = TU ;
247
- bestVTUa = VTUa ;
248
- bestVTUf = VTUf ;
249
- bestVTUi = VTUi ;
250
- if (diff == 0 )
251
- break ;
252
- }
253
- }
254
-
255
- if (!bestTU ) {
256
- NV_ERROR (dev , "DP: unable to find suitable config\n" );
257
- return ;
258
- }
259
-
260
- /* XXX close to vbios numbers, but not right */
261
- unk = (symbol - link_ratio ) * bestTU ;
262
- unk *= link_ratio ;
263
- r = do_div (unk , symbol );
264
- r = do_div (unk , symbol );
265
- unk += 6 ;
266
-
267
- nv_mask (dev , NV50_SOR_DP_CTRL (or , link ), 0x000001fc , bestTU << 2 );
268
- nv_mask (dev , NV50_SOR_DP_SCFG (or , link ), 0x010f7f3f , bestVTUa << 24 |
269
- bestVTUf << 16 |
270
- bestVTUi << 8 |
271
- unk );
272
- }
273
-
274
164
u8 *
275
165
nouveau_dp_bios_data (struct drm_device * dev , struct dcb_entry * dcb , u8 * * entry )
276
166
{
@@ -318,13 +208,10 @@ nouveau_dp_bios_data(struct drm_device *dev, struct dcb_entry *dcb, u8 **entry)
318
208
* link training
319
209
*****************************************************************************/
320
210
struct dp_state {
211
+ struct dp_train_func * func ;
321
212
struct dcb_entry * dcb ;
322
- u8 * table ;
323
- u8 * entry ;
324
213
int auxch ;
325
214
int crtc ;
326
- int or ;
327
- int link ;
328
215
u8 * dpcd ;
329
216
int link_nr ;
330
217
u32 link_bw ;
@@ -335,142 +222,58 @@ struct dp_state {
335
222
static void
336
223
dp_set_link_config (struct drm_device * dev , struct dp_state * dp )
337
224
{
338
- int or = dp -> or , link = dp -> link ;
339
- u8 * entry , sink [2 ];
340
- u32 dp_ctrl ;
341
- u16 script ;
225
+ u8 sink [2 ];
342
226
343
227
NV_DEBUG_KMS (dev , "%d lanes at %d KB/s\n" , dp -> link_nr , dp -> link_bw );
344
228
345
- /* set selected link rate on source */
346
- switch (dp -> link_bw ) {
347
- case 270000 :
348
- nv_mask (dev , 0x614300 + (or * 0x800 ), 0x000c0000 , 0x00040000 );
349
- sink [0 ] = DP_LINK_BW_2_7 ;
350
- break ;
351
- default :
352
- nv_mask (dev , 0x614300 + (or * 0x800 ), 0x000c0000 , 0x00000000 );
353
- sink [0 ] = DP_LINK_BW_1_62 ;
354
- break ;
355
- }
356
-
357
- /* offset +0x0a of each dp encoder table entry is a pointer to another
358
- * table, that has (among other things) pointers to more scripts that
359
- * need to be executed, this time depending on link speed.
360
- */
361
- entry = ROMPTR (dev , dp -> entry [10 ]);
362
- if (entry ) {
363
- if (dp -> table [0 ] < 0x30 ) {
364
- while (dp -> link_bw < (ROM16 (entry [0 ]) * 10 ))
365
- entry += 4 ;
366
- script = ROM16 (entry [2 ]);
367
- } else {
368
- while (dp -> link_bw < (entry [0 ] * 27000 ))
369
- entry += 3 ;
370
- script = ROM16 (entry [1 ]);
371
- }
229
+ /* set desired link configuration on the source */
230
+ dp -> func -> link_set (dev , dp -> dcb , dp -> crtc , dp -> link_nr , dp -> link_bw ,
231
+ dp -> dpcd [2 ] & DP_ENHANCED_FRAME_CAP );
372
232
373
- nouveau_bios_run_init_table (dev , script , dp -> dcb , dp -> crtc );
374
- }
375
-
376
- /* configure lane count on the source */
377
- dp_ctrl = ((1 << dp -> link_nr ) - 1 ) << 16 ;
233
+ /* inform the sink of the new configuration */
234
+ sink [0 ] = dp -> link_bw / 27000 ;
378
235
sink [1 ] = dp -> link_nr ;
379
- if (dp -> dpcd [2 ] & DP_ENHANCED_FRAME_CAP ) {
380
- dp_ctrl |= 0x00004000 ;
236
+ if (dp -> dpcd [2 ] & DP_ENHANCED_FRAME_CAP )
381
237
sink [1 ] |= DP_LANE_COUNT_ENHANCED_FRAME_EN ;
382
- }
383
-
384
- nv_mask (dev , NV50_SOR_DP_CTRL (or , link ), 0x001f4000 , dp_ctrl );
385
238
386
- /* inform the sink of the new configuration */
387
239
auxch_tx (dev , dp -> auxch , 8 , DP_LINK_BW_SET , sink , 2 );
388
240
}
389
241
390
242
static void
391
- dp_set_training_pattern (struct drm_device * dev , struct dp_state * dp , u8 tp )
243
+ dp_set_training_pattern (struct drm_device * dev , struct dp_state * dp , u8 pattern )
392
244
{
393
245
u8 sink_tp ;
394
246
395
- NV_DEBUG_KMS (dev , "training pattern %d\n" , tp );
247
+ NV_DEBUG_KMS (dev , "training pattern %d\n" , pattern );
396
248
397
- nv_mask ( dev , NV50_SOR_DP_CTRL ( dp -> or , dp -> link ), 0x0f000000 , tp << 24 );
249
+ dp -> func -> train_set ( dev , dp -> dcb , pattern );
398
250
399
251
auxch_tx (dev , dp -> auxch , 9 , DP_TRAINING_PATTERN_SET , & sink_tp , 1 );
400
252
sink_tp &= ~DP_TRAINING_PATTERN_MASK ;
401
- sink_tp |= tp ;
253
+ sink_tp |= pattern ;
402
254
auxch_tx (dev , dp -> auxch , 8 , DP_TRAINING_PATTERN_SET , & sink_tp , 1 );
403
255
}
404
256
405
- static const u8 nv50_lane_map [] = { 16 , 8 , 0 , 24 };
406
- static const u8 nvaf_lane_map [] = { 24 , 16 , 8 , 0 };
407
-
408
257
static int
409
258
dp_link_train_commit (struct drm_device * dev , struct dp_state * dp )
410
259
{
411
- struct drm_nouveau_private * dev_priv = dev -> dev_private ;
412
- u32 mask = 0 , drv = 0 , pre = 0 , unk = 0 ;
413
- const u8 * shifts ;
414
- int link = dp -> link ;
415
- int or = dp -> or ;
416
260
int i ;
417
261
418
- if (dev_priv -> chipset != 0xaf )
419
- shifts = nv50_lane_map ;
420
- else
421
- shifts = nvaf_lane_map ;
422
-
423
262
for (i = 0 ; i < dp -> link_nr ; i ++ ) {
424
- u8 * conf = dp -> entry + dp -> table [4 ];
425
263
u8 lane = (dp -> stat [4 + (i >> 1 )] >> ((i & 1 ) * 4 )) & 0xf ;
426
264
u8 lpre = (lane & 0x0c ) >> 2 ;
427
265
u8 lvsw = (lane & 0x03 ) >> 0 ;
428
266
429
- mask |= 0xff << shifts [i ];
430
- unk |= 1 << (shifts [i ] >> 3 );
431
-
432
267
dp -> conf [i ] = (lpre << 3 ) | lvsw ;
433
268
if (lvsw == DP_TRAIN_VOLTAGE_SWING_1200 )
434
269
dp -> conf [i ] |= DP_TRAIN_MAX_SWING_REACHED ;
435
270
if ((lpre << 3 ) == DP_TRAIN_PRE_EMPHASIS_9_5 )
436
271
dp -> conf [i ] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED ;
437
272
438
273
NV_DEBUG_KMS (dev , "config lane %d %02x\n" , i , dp -> conf [i ]);
439
-
440
- if (dp -> table [0 ] < 0x30 ) {
441
- u8 * last = conf + (dp -> entry [4 ] * dp -> table [5 ]);
442
- while (lvsw != conf [0 ] || lpre != conf [1 ]) {
443
- conf += dp -> table [5 ];
444
- if (conf >= last )
445
- return - EINVAL ;
446
- }
447
-
448
- conf += 2 ;
449
- } else {
450
- /* no lookup table anymore, set entries for each
451
- * combination of voltage swing and pre-emphasis
452
- * level allowed by the DP spec.
453
- */
454
- switch (lvsw ) {
455
- case 0 : lpre += 0 ; break ;
456
- case 1 : lpre += 4 ; break ;
457
- case 2 : lpre += 7 ; break ;
458
- case 3 : lpre += 9 ; break ;
459
- }
460
-
461
- conf = conf + (lpre * dp -> table [5 ]);
462
- conf ++ ;
463
- }
464
-
465
- drv |= conf [0 ] << shifts [i ];
466
- pre |= conf [1 ] << shifts [i ];
467
- unk = (unk & ~0x0000ff00 ) | (conf [2 ] << 8 );
274
+ dp -> func -> train_adj (dev , dp -> dcb , i , lvsw , lpre );
468
275
}
469
276
470
- nv_mask (dev , NV50_SOR_DP_UNK118 (or , link ), mask , drv );
471
- nv_mask (dev , NV50_SOR_DP_UNK120 (or , link ), mask , pre );
472
- nv_mask (dev , NV50_SOR_DP_UNK130 (or , link ), 0x0000ff0f , unk );
473
-
474
277
return auxch_tx (dev , dp -> auxch , 8 , DP_TRAINING_LANE0_SET , dp -> conf , 4 );
475
278
}
476
279
@@ -598,7 +401,8 @@ dp_link_train_fini(struct drm_device *dev, struct dp_state *dp)
598
401
}
599
402
600
403
bool
601
- nouveau_dp_link_train (struct drm_encoder * encoder , u32 datarate )
404
+ nouveau_dp_link_train (struct drm_encoder * encoder , u32 datarate ,
405
+ struct dp_train_func * func )
602
406
{
603
407
struct nouveau_encoder * nv_encoder = nouveau_encoder (encoder );
604
408
struct nouveau_crtc * nv_crtc = nouveau_crtc (encoder -> crtc );
@@ -614,15 +418,10 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate)
614
418
if (!auxch )
615
419
return false;
616
420
617
- dp .table = nouveau_dp_bios_data (dev , nv_encoder -> dcb , & dp .entry );
618
- if (!dp .table )
619
- return - EINVAL ;
620
-
421
+ dp .func = func ;
621
422
dp .dcb = nv_encoder -> dcb ;
622
423
dp .crtc = nv_crtc -> index ;
623
424
dp .auxch = auxch -> drive ;
624
- dp .or = nv_encoder -> or ;
625
- dp .link = !(nv_encoder -> dcb -> sorconf .link & 1 );
626
425
dp .dpcd = nv_encoder -> dp .dpcd ;
627
426
628
427
/* some sinks toggle hotplug in response to some of the actions
0 commit comments