1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "dm_services.h"
26
27#include "link_encoder.h"
28#include "stream_encoder.h"
29
30#include "resource.h"
31#include "include/irq_service_interface.h"
32#include "../virtual/virtual_stream_encoder.h"
33#include "dce110/dce110_resource.h"
34#include "dce110/dce110_timing_generator.h"
35#include "irq/dce110/irq_service_dce110.h"
36#include "dce/dce_link_encoder.h"
37#include "dce/dce_stream_encoder.h"
38
39#include "dce/dce_clk_mgr.h"
40#include "dce/dce_mem_input.h"
41#include "dce/dce_ipp.h"
42#include "dce/dce_transform.h"
43#include "dce/dce_opp.h"
44#include "dce/dce_clock_source.h"
45#include "dce/dce_audio.h"
46#include "dce/dce_hwseq.h"
47#include "dce100/dce100_hw_sequencer.h"
48
49#include "reg_helper.h"
50
51#include "dce/dce_10_0_d.h"
52#include "dce/dce_10_0_sh_mask.h"
53
54#include "dce/dce_dmcu.h"
55#include "dce/dce_aux.h"
56#include "dce/dce_abm.h"
57#include "dce/dce_i2c.h"
58
59#ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
60#include "gmc/gmc_8_2_d.h"
61#include "gmc/gmc_8_2_sh_mask.h"
62#endif
63
64#ifndef mmDP_DPHY_INTERNAL_CTRL
65 #define mmDP_DPHY_INTERNAL_CTRL 0x4aa7
66 #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x4aa7
67 #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x4ba7
68 #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x4ca7
69 #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x4da7
70 #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x4ea7
71 #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x4fa7
72 #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x54a7
73 #define mmDP7_DP_DPHY_INTERNAL_CTRL 0x56a7
74 #define mmDP8_DP_DPHY_INTERNAL_CTRL 0x57a7
75#endif
76
77#ifndef mmBIOS_SCRATCH_2
78 #define mmBIOS_SCRATCH_2 0x05CB
79 #define mmBIOS_SCRATCH_3 0x05CC
80 #define mmBIOS_SCRATCH_6 0x05CF
81#endif
82
83#ifndef mmDP_DPHY_BS_SR_SWAP_CNTL
84 #define mmDP_DPHY_BS_SR_SWAP_CNTL 0x4ADC
85 #define mmDP0_DP_DPHY_BS_SR_SWAP_CNTL 0x4ADC
86 #define mmDP1_DP_DPHY_BS_SR_SWAP_CNTL 0x4BDC
87 #define mmDP2_DP_DPHY_BS_SR_SWAP_CNTL 0x4CDC
88 #define mmDP3_DP_DPHY_BS_SR_SWAP_CNTL 0x4DDC
89 #define mmDP4_DP_DPHY_BS_SR_SWAP_CNTL 0x4EDC
90 #define mmDP5_DP_DPHY_BS_SR_SWAP_CNTL 0x4FDC
91 #define mmDP6_DP_DPHY_BS_SR_SWAP_CNTL 0x54DC
92#endif
93
94#ifndef mmDP_DPHY_FAST_TRAINING
95 #define mmDP_DPHY_FAST_TRAINING 0x4ABC
96 #define mmDP0_DP_DPHY_FAST_TRAINING 0x4ABC
97 #define mmDP1_DP_DPHY_FAST_TRAINING 0x4BBC
98 #define mmDP2_DP_DPHY_FAST_TRAINING 0x4CBC
99 #define mmDP3_DP_DPHY_FAST_TRAINING 0x4DBC
100 #define mmDP4_DP_DPHY_FAST_TRAINING 0x4EBC
101 #define mmDP5_DP_DPHY_FAST_TRAINING 0x4FBC
102 #define mmDP6_DP_DPHY_FAST_TRAINING 0x54BC
103#endif
104
105static const struct dce110_timing_generator_offsets dce100_tg_offsets[] = {
106 {
107 .crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL),
108 .dcp = (mmDCP0_GRPH_CONTROL - mmGRPH_CONTROL),
109 },
110 {
111 .crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL),
112 .dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL),
113 },
114 {
115 .crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL),
116 .dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL),
117 },
118 {
119 .crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL),
120 .dcp = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL),
121 },
122 {
123 .crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL),
124 .dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL),
125 },
126 {
127 .crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL),
128 .dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL),
129 }
130};
131
132
133#define SR(reg_name)\
134 .reg_name = mm ## reg_name
135
136
137#define SRI(reg_name, block, id)\
138 .reg_name = mm ## block ## id ## _ ## reg_name
139
140
141static const struct clk_mgr_registers disp_clk_regs = {
142 CLK_COMMON_REG_LIST_DCE_BASE()
143};
144
145static const struct clk_mgr_shift disp_clk_shift = {
146 CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
147};
148
149static const struct clk_mgr_mask disp_clk_mask = {
150 CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
151};
152
153#define ipp_regs(id)\
154[id] = {\
155 IPP_DCE100_REG_LIST_DCE_BASE(id)\
156}
157
158static const struct dce_ipp_registers ipp_regs[] = {
159 ipp_regs(0),
160 ipp_regs(1),
161 ipp_regs(2),
162 ipp_regs(3),
163 ipp_regs(4),
164 ipp_regs(5)
165};
166
167static const struct dce_ipp_shift ipp_shift = {
168 IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
169};
170
171static const struct dce_ipp_mask ipp_mask = {
172 IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
173};
174
175#define transform_regs(id)\
176[id] = {\
177 XFM_COMMON_REG_LIST_DCE100(id)\
178}
179
180static const struct dce_transform_registers xfm_regs[] = {
181 transform_regs(0),
182 transform_regs(1),
183 transform_regs(2),
184 transform_regs(3),
185 transform_regs(4),
186 transform_regs(5)
187};
188
189static const struct dce_transform_shift xfm_shift = {
190 XFM_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
191};
192
193static const struct dce_transform_mask xfm_mask = {
194 XFM_COMMON_MASK_SH_LIST_DCE110(_MASK)
195};
196
197#define aux_regs(id)\
198[id] = {\
199 AUX_REG_LIST(id)\
200}
201
202static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
203 aux_regs(0),
204 aux_regs(1),
205 aux_regs(2),
206 aux_regs(3),
207 aux_regs(4),
208 aux_regs(5)
209};
210
211#define hpd_regs(id)\
212[id] = {\
213 HPD_REG_LIST(id)\
214}
215
216static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
217 hpd_regs(0),
218 hpd_regs(1),
219 hpd_regs(2),
220 hpd_regs(3),
221 hpd_regs(4),
222 hpd_regs(5)
223};
224
225#define link_regs(id)\
226[id] = {\
227 LE_DCE100_REG_LIST(id)\
228}
229
230static const struct dce110_link_enc_registers link_enc_regs[] = {
231 link_regs(0),
232 link_regs(1),
233 link_regs(2),
234 link_regs(3),
235 link_regs(4),
236 link_regs(5),
237 link_regs(6),
238};
239
240#define stream_enc_regs(id)\
241[id] = {\
242 SE_COMMON_REG_LIST_DCE_BASE(id),\
243 .AFMT_CNTL = 0,\
244}
245
246static const struct dce110_stream_enc_registers stream_enc_regs[] = {
247 stream_enc_regs(0),
248 stream_enc_regs(1),
249 stream_enc_regs(2),
250 stream_enc_regs(3),
251 stream_enc_regs(4),
252 stream_enc_regs(5),
253 stream_enc_regs(6)
254};
255
256static const struct dce_stream_encoder_shift se_shift = {
257 SE_COMMON_MASK_SH_LIST_DCE80_100(__SHIFT)
258};
259
260static const struct dce_stream_encoder_mask se_mask = {
261 SE_COMMON_MASK_SH_LIST_DCE80_100(_MASK)
262};
263
264#define opp_regs(id)\
265[id] = {\
266 OPP_DCE_100_REG_LIST(id),\
267}
268
269static const struct dce_opp_registers opp_regs[] = {
270 opp_regs(0),
271 opp_regs(1),
272 opp_regs(2),
273 opp_regs(3),
274 opp_regs(4),
275 opp_regs(5)
276};
277
278static const struct dce_opp_shift opp_shift = {
279 OPP_COMMON_MASK_SH_LIST_DCE_100(__SHIFT)
280};
281
282static const struct dce_opp_mask opp_mask = {
283 OPP_COMMON_MASK_SH_LIST_DCE_100(_MASK)
284};
285#define aux_engine_regs(id)\
286[id] = {\
287 AUX_COMMON_REG_LIST(id), \
288 .AUX_RESET_MASK = 0 \
289}
290
291static const struct dce110_aux_registers aux_engine_regs[] = {
292 aux_engine_regs(0),
293 aux_engine_regs(1),
294 aux_engine_regs(2),
295 aux_engine_regs(3),
296 aux_engine_regs(4),
297 aux_engine_regs(5)
298};
299
300#define audio_regs(id)\
301[id] = {\
302 AUD_COMMON_REG_LIST(id)\
303}
304
305static const struct dce_audio_registers audio_regs[] = {
306 audio_regs(0),
307 audio_regs(1),
308 audio_regs(2),
309 audio_regs(3),
310 audio_regs(4),
311 audio_regs(5),
312 audio_regs(6),
313};
314
315static const struct dce_audio_shift audio_shift = {
316 AUD_COMMON_MASK_SH_LIST(__SHIFT)
317};
318
319static const struct dce_aduio_mask audio_mask = {
320 AUD_COMMON_MASK_SH_LIST(_MASK)
321};
322
323#define clk_src_regs(id)\
324[id] = {\
325 CS_COMMON_REG_LIST_DCE_100_110(id),\
326}
327
328static const struct dce110_clk_src_regs clk_src_regs[] = {
329 clk_src_regs(0),
330 clk_src_regs(1),
331 clk_src_regs(2)
332};
333
334static const struct dce110_clk_src_shift cs_shift = {
335 CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
336};
337
338static const struct dce110_clk_src_mask cs_mask = {
339 CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
340};
341
342static const struct dce_dmcu_registers dmcu_regs = {
343 DMCU_DCE110_COMMON_REG_LIST()
344};
345
346static const struct dce_dmcu_shift dmcu_shift = {
347 DMCU_MASK_SH_LIST_DCE110(__SHIFT)
348};
349
350static const struct dce_dmcu_mask dmcu_mask = {
351 DMCU_MASK_SH_LIST_DCE110(_MASK)
352};
353
354static const struct dce_abm_registers abm_regs = {
355 ABM_DCE110_COMMON_REG_LIST()
356};
357
358static const struct dce_abm_shift abm_shift = {
359 ABM_MASK_SH_LIST_DCE110(__SHIFT)
360};
361
362static const struct dce_abm_mask abm_mask = {
363 ABM_MASK_SH_LIST_DCE110(_MASK)
364};
365
366#define DCFE_MEM_PWR_CTRL_REG_BASE 0x1b03
367
368static const struct bios_registers bios_regs = {
369 .BIOS_SCRATCH_3 = mmBIOS_SCRATCH_3,
370 .BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6
371};
372
373static const struct resource_caps res_cap = {
374 .num_timing_generator = 6,
375 .num_audio = 6,
376 .num_stream_encoder = 6,
377 .num_pll = 3,
378 .num_ddc = 6,
379};
380
381#define CTX ctx
382#define REG(reg) mm ## reg
383
384#ifndef mmCC_DC_HDMI_STRAPS
385#define mmCC_DC_HDMI_STRAPS 0x1918
386#define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40
387#define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6
388#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700
389#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
390#endif
391
392static void read_dce_straps(
393 struct dc_context *ctx,
394 struct resource_straps *straps)
395{
396 REG_GET_2(CC_DC_HDMI_STRAPS,
397 HDMI_DISABLE, &straps->hdmi_disable,
398 AUDIO_STREAM_NUMBER, &straps->audio_stream_number);
399
400 REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio);
401}
402
403static struct audio *create_audio(
404 struct dc_context *ctx, unsigned int inst)
405{
406 return dce_audio_create(ctx, inst,
407 &audio_regs[inst], &audio_shift, &audio_mask);
408}
409
410static struct timing_generator *dce100_timing_generator_create(
411 struct dc_context *ctx,
412 uint32_t instance,
413 const struct dce110_timing_generator_offsets *offsets)
414{
415 struct dce110_timing_generator *tg110 =
416 kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL);
417
418 if (!tg110)
419 return NULL;
420
421 dce110_timing_generator_construct(tg110, ctx, instance, offsets);
422 return &tg110->base;
423}
424
425static struct stream_encoder *dce100_stream_encoder_create(
426 enum engine_id eng_id,
427 struct dc_context *ctx)
428{
429 struct dce110_stream_encoder *enc110 =
430 kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL);
431
432 if (!enc110)
433 return NULL;
434
435 dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
436 &stream_enc_regs[eng_id], &se_shift, &se_mask);
437 return &enc110->base;
438}
439
440#define SRII(reg_name, block, id)\
441 .reg_name[id] = mm ## block ## id ## _ ## reg_name
442
443static const struct dce_hwseq_registers hwseq_reg = {
444 HWSEQ_DCE10_REG_LIST()
445};
446
447static const struct dce_hwseq_shift hwseq_shift = {
448 HWSEQ_DCE10_MASK_SH_LIST(__SHIFT)
449};
450
451static const struct dce_hwseq_mask hwseq_mask = {
452 HWSEQ_DCE10_MASK_SH_LIST(_MASK)
453};
454
455static struct dce_hwseq *dce100_hwseq_create(
456 struct dc_context *ctx)
457{
458 struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
459
460 if (hws) {
461 hws->ctx = ctx;
462 hws->regs = &hwseq_reg;
463 hws->shifts = &hwseq_shift;
464 hws->masks = &hwseq_mask;
465 }
466 return hws;
467}
468
469static const struct resource_create_funcs res_create_funcs = {
470 .read_dce_straps = read_dce_straps,
471 .create_audio = create_audio,
472 .create_stream_encoder = dce100_stream_encoder_create,
473 .create_hwseq = dce100_hwseq_create,
474};
475
476#define mi_inst_regs(id) { \
477 MI_DCE8_REG_LIST(id), \
478 .MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \
479}
480static const struct dce_mem_input_registers mi_regs[] = {
481 mi_inst_regs(0),
482 mi_inst_regs(1),
483 mi_inst_regs(2),
484 mi_inst_regs(3),
485 mi_inst_regs(4),
486 mi_inst_regs(5),
487};
488
489static const struct dce_mem_input_shift mi_shifts = {
490 MI_DCE8_MASK_SH_LIST(__SHIFT),
491 .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT
492};
493
494static const struct dce_mem_input_mask mi_masks = {
495 MI_DCE8_MASK_SH_LIST(_MASK),
496 .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK
497};
498
499static struct mem_input *dce100_mem_input_create(
500 struct dc_context *ctx,
501 uint32_t inst)
502{
503 struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input),
504 GFP_KERNEL);
505
506 if (!dce_mi) {
507 BREAK_TO_DEBUGGER();
508 return NULL;
509 }
510
511 dce_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks);
512 dce_mi->wa.single_head_rdreq_dmif_limit = 2;
513 return &dce_mi->base;
514}
515
516static void dce100_transform_destroy(struct transform **xfm)
517{
518 kfree(TO_DCE_TRANSFORM(*xfm));
519 *xfm = NULL;
520}
521
522static struct transform *dce100_transform_create(
523 struct dc_context *ctx,
524 uint32_t inst)
525{
526 struct dce_transform *transform =
527 kzalloc(sizeof(struct dce_transform), GFP_KERNEL);
528
529 if (!transform)
530 return NULL;
531
532 dce_transform_construct(transform, ctx, inst,
533 &xfm_regs[inst], &xfm_shift, &xfm_mask);
534 return &transform->base;
535}
536
537static struct input_pixel_processor *dce100_ipp_create(
538 struct dc_context *ctx, uint32_t inst)
539{
540 struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL);
541
542 if (!ipp) {
543 BREAK_TO_DEBUGGER();
544 return NULL;
545 }
546
547 dce_ipp_construct(ipp, ctx, inst,
548 &ipp_regs[inst], &ipp_shift, &ipp_mask);
549 return &ipp->base;
550}
551
552static const struct encoder_feature_support link_enc_feature = {
553 .max_hdmi_deep_color = COLOR_DEPTH_121212,
554 .max_hdmi_pixel_clock = 300000,
555 .flags.bits.IS_HBR2_CAPABLE = true,
556 .flags.bits.IS_TPS3_CAPABLE = true
557};
558
559struct link_encoder *dce100_link_encoder_create(
560 const struct encoder_init_data *enc_init_data)
561{
562 struct dce110_link_encoder *enc110 =
563 kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
564
565 if (!enc110)
566 return NULL;
567
568 dce110_link_encoder_construct(enc110,
569 enc_init_data,
570 &link_enc_feature,
571 &link_enc_regs[enc_init_data->transmitter],
572 &link_enc_aux_regs[enc_init_data->channel - 1],
573 &link_enc_hpd_regs[enc_init_data->hpd_source]);
574 return &enc110->base;
575}
576
577struct output_pixel_processor *dce100_opp_create(
578 struct dc_context *ctx,
579 uint32_t inst)
580{
581 struct dce110_opp *opp =
582 kzalloc(sizeof(struct dce110_opp), GFP_KERNEL);
583
584 if (!opp)
585 return NULL;
586
587 dce110_opp_construct(opp,
588 ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask);
589 return &opp->base;
590}
591
592struct dce_aux *dce100_aux_engine_create(
593 struct dc_context *ctx,
594 uint32_t inst)
595{
596 struct aux_engine_dce110 *aux_engine =
597 kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
598
599 if (!aux_engine)
600 return NULL;
601
602 dce110_aux_engine_construct(aux_engine, ctx, inst,
603 SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
604 &aux_engine_regs[inst]);
605
606 return &aux_engine->base;
607}
608#define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
609
610static const struct dce_i2c_registers i2c_hw_regs[] = {
611 i2c_inst_regs(1),
612 i2c_inst_regs(2),
613 i2c_inst_regs(3),
614 i2c_inst_regs(4),
615 i2c_inst_regs(5),
616 i2c_inst_regs(6),
617};
618
619static const struct dce_i2c_shift i2c_shifts = {
620 I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
621};
622
623static const struct dce_i2c_mask i2c_masks = {
624 I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
625};
626
627struct dce_i2c_hw *dce100_i2c_hw_create(
628 struct dc_context *ctx,
629 uint32_t inst)
630{
631 struct dce_i2c_hw *dce_i2c_hw =
632 kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
633
634 if (!dce_i2c_hw)
635 return NULL;
636
637 dce100_i2c_hw_construct(dce_i2c_hw, ctx, inst,
638 &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
639
640 return dce_i2c_hw;
641}
642struct clock_source *dce100_clock_source_create(
643 struct dc_context *ctx,
644 struct dc_bios *bios,
645 enum clock_source_id id,
646 const struct dce110_clk_src_regs *regs,
647 bool dp_clk_src)
648{
649 struct dce110_clk_src *clk_src =
650 kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
651
652 if (!clk_src)
653 return NULL;
654
655 if (dce110_clk_src_construct(clk_src, ctx, bios, id,
656 regs, &cs_shift, &cs_mask)) {
657 clk_src->base.dp_clk_src = dp_clk_src;
658 return &clk_src->base;
659 }
660
661 BREAK_TO_DEBUGGER();
662 return NULL;
663}
664
665void dce100_clock_source_destroy(struct clock_source **clk_src)
666{
667 kfree(TO_DCE110_CLK_SRC(*clk_src));
668 *clk_src = NULL;
669}
670
671static void destruct(struct dce110_resource_pool *pool)
672{
673 unsigned int i;
674
675 for (i = 0; i < pool->base.pipe_count; i++) {
676 if (pool->base.opps[i] != NULL)
677 dce110_opp_destroy(&pool->base.opps[i]);
678
679 if (pool->base.transforms[i] != NULL)
680 dce100_transform_destroy(&pool->base.transforms[i]);
681
682 if (pool->base.ipps[i] != NULL)
683 dce_ipp_destroy(&pool->base.ipps[i]);
684
685 if (pool->base.mis[i] != NULL) {
686 kfree(TO_DCE_MEM_INPUT(pool->base.mis[i]));
687 pool->base.mis[i] = NULL;
688 }
689
690 if (pool->base.timing_generators[i] != NULL) {
691 kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i]));
692 pool->base.timing_generators[i] = NULL;
693 }
694 }
695
696 for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
697 if (pool->base.engines[i] != NULL)
698 dce110_engine_destroy(&pool->base.engines[i]);
699 if (pool->base.hw_i2cs[i] != NULL) {
700 kfree(pool->base.hw_i2cs[i]);
701 pool->base.hw_i2cs[i] = NULL;
702 }
703 if (pool->base.sw_i2cs[i] != NULL) {
704 kfree(pool->base.sw_i2cs[i]);
705 pool->base.sw_i2cs[i] = NULL;
706 }
707 }
708
709 for (i = 0; i < pool->base.stream_enc_count; i++) {
710 if (pool->base.stream_enc[i] != NULL)
711 kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));
712 }
713
714 for (i = 0; i < pool->base.clk_src_count; i++) {
715 if (pool->base.clock_sources[i] != NULL)
716 dce100_clock_source_destroy(&pool->base.clock_sources[i]);
717 }
718
719 if (pool->base.dp_clock_source != NULL)
720 dce100_clock_source_destroy(&pool->base.dp_clock_source);
721
722 for (i = 0; i < pool->base.audio_count; i++) {
723 if (pool->base.audios[i] != NULL)
724 dce_aud_destroy(&pool->base.audios[i]);
725 }
726
727 if (pool->base.clk_mgr != NULL)
728 dce_clk_mgr_destroy(&pool->base.clk_mgr);
729
730 if (pool->base.abm != NULL)
731 dce_abm_destroy(&pool->base.abm);
732
733 if (pool->base.dmcu != NULL)
734 dce_dmcu_destroy(&pool->base.dmcu);
735
736 if (pool->base.irqs != NULL)
737 dal_irq_service_destroy(&pool->base.irqs);
738}
739
740static enum dc_status build_mapped_resource(
741 const struct dc *dc,
742 struct dc_state *context,
743 struct dc_stream_state *stream)
744{
745 struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream);
746
747 if (!pipe_ctx)
748 return DC_ERROR_UNEXPECTED;
749
750 dce110_resource_build_pipe_hw_param(pipe_ctx);
751
752 resource_build_info_frame(pipe_ctx);
753
754 return DC_OK;
755}
756
757bool dce100_validate_bandwidth(
758 struct dc *dc,
759 struct dc_state *context)
760{
761 int i;
762 bool at_least_one_pipe = false;
763
764 for (i = 0; i < dc->res_pool->pipe_count; i++) {
765 if (context->res_ctx.pipe_ctx[i].stream)
766 at_least_one_pipe = true;
767 }
768
769 if (at_least_one_pipe) {
770
771 context->bw.dce.dispclk_khz = 681000;
772 context->bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER_CZ;
773 } else {
774 context->bw.dce.dispclk_khz = 0;
775 context->bw.dce.yclk_khz = 0;
776 }
777
778 return true;
779}
780
781static bool dce100_validate_surface_sets(
782 struct dc_state *context)
783{
784 int i;
785
786 for (i = 0; i < context->stream_count; i++) {
787 if (context->stream_status[i].plane_count == 0)
788 continue;
789
790 if (context->stream_status[i].plane_count > 1)
791 return false;
792
793 if (context->stream_status[i].plane_states[0]->format
794 >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
795 return false;
796 }
797
798 return true;
799}
800
801enum dc_status dce100_validate_global(
802 struct dc *dc,
803 struct dc_state *context)
804{
805 if (!dce100_validate_surface_sets(context))
806 return DC_FAIL_SURFACE_VALIDATE;
807
808 return DC_OK;
809}
810
811enum dc_status dce100_add_stream_to_ctx(
812 struct dc *dc,
813 struct dc_state *new_ctx,
814 struct dc_stream_state *dc_stream)
815{
816 enum dc_status result = DC_ERROR_UNEXPECTED;
817
818 result = resource_map_pool_resources(dc, new_ctx, dc_stream);
819
820 if (result == DC_OK)
821 result = resource_map_clock_resources(dc, new_ctx, dc_stream);
822
823 if (result == DC_OK)
824 result = build_mapped_resource(dc, new_ctx, dc_stream);
825
826 return result;
827}
828
829static void dce100_destroy_resource_pool(struct resource_pool **pool)
830{
831 struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
832
833 destruct(dce110_pool);
834 kfree(dce110_pool);
835 *pool = NULL;
836}
837
838enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, struct dc_caps *caps)
839{
840
841 if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
842 return DC_OK;
843
844 return DC_FAIL_SURFACE_VALIDATE;
845}
846
847static const struct resource_funcs dce100_res_pool_funcs = {
848 .destroy = dce100_destroy_resource_pool,
849 .link_enc_create = dce100_link_encoder_create,
850 .validate_bandwidth = dce100_validate_bandwidth,
851 .validate_plane = dce100_validate_plane,
852 .add_stream_to_ctx = dce100_add_stream_to_ctx,
853 .validate_global = dce100_validate_global
854};
855
856static bool construct(
857 uint8_t num_virtual_links,
858 struct dc *dc,
859 struct dce110_resource_pool *pool)
860{
861 unsigned int i;
862 struct dc_context *ctx = dc->ctx;
863 struct dc_firmware_info info;
864 struct dc_bios *bp;
865
866 ctx->dc_bios->regs = &bios_regs;
867
868 pool->base.res_cap = &res_cap;
869 pool->base.funcs = &dce100_res_pool_funcs;
870 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
871
872 bp = ctx->dc_bios;
873
874 if ((bp->funcs->get_firmware_info(bp, &info) == BP_RESULT_OK) &&
875 info.external_clock_source_frequency_for_dp != 0) {
876 pool->base.dp_clock_source =
877 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
878
879 pool->base.clock_sources[0] =
880 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], false);
881 pool->base.clock_sources[1] =
882 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
883 pool->base.clock_sources[2] =
884 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
885 pool->base.clk_src_count = 3;
886
887 } else {
888 pool->base.dp_clock_source =
889 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0, &clk_src_regs[0], true);
890
891 pool->base.clock_sources[0] =
892 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1, &clk_src_regs[1], false);
893 pool->base.clock_sources[1] =
894 dce100_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL2, &clk_src_regs[2], false);
895 pool->base.clk_src_count = 2;
896 }
897
898 if (pool->base.dp_clock_source == NULL) {
899 dm_error("DC: failed to create dp clock source!\n");
900 BREAK_TO_DEBUGGER();
901 goto res_create_fail;
902 }
903
904 for (i = 0; i < pool->base.clk_src_count; i++) {
905 if (pool->base.clock_sources[i] == NULL) {
906 dm_error("DC: failed to create clock sources!\n");
907 BREAK_TO_DEBUGGER();
908 goto res_create_fail;
909 }
910 }
911
912 pool->base.clk_mgr = dce_clk_mgr_create(ctx,
913 &disp_clk_regs,
914 &disp_clk_shift,
915 &disp_clk_mask);
916 if (pool->base.clk_mgr == NULL) {
917 dm_error("DC: failed to create display clock!\n");
918 BREAK_TO_DEBUGGER();
919 goto res_create_fail;
920 }
921
922 pool->base.dmcu = dce_dmcu_create(ctx,
923 &dmcu_regs,
924 &dmcu_shift,
925 &dmcu_mask);
926 if (pool->base.dmcu == NULL) {
927 dm_error("DC: failed to create dmcu!\n");
928 BREAK_TO_DEBUGGER();
929 goto res_create_fail;
930 }
931
932 pool->base.abm = dce_abm_create(ctx,
933 &abm_regs,
934 &abm_shift,
935 &abm_mask);
936 if (pool->base.abm == NULL) {
937 dm_error("DC: failed to create abm!\n");
938 BREAK_TO_DEBUGGER();
939 goto res_create_fail;
940 }
941
942 {
943 struct irq_service_init_data init_data;
944 init_data.ctx = dc->ctx;
945 pool->base.irqs = dal_irq_service_dce110_create(&init_data);
946 if (!pool->base.irqs)
947 goto res_create_fail;
948 }
949
950
951
952
953 pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
954 pool->base.pipe_count = res_cap.num_timing_generator;
955 pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator;
956 dc->caps.max_downscale_ratio = 200;
957 dc->caps.i2c_speed_in_khz = 40;
958 dc->caps.max_cursor_size = 128;
959 dc->caps.dual_link_dvi = true;
960 dc->caps.disable_dp_clk_share = true;
961 for (i = 0; i < pool->base.pipe_count; i++) {
962 pool->base.timing_generators[i] =
963 dce100_timing_generator_create(
964 ctx,
965 i,
966 &dce100_tg_offsets[i]);
967 if (pool->base.timing_generators[i] == NULL) {
968 BREAK_TO_DEBUGGER();
969 dm_error("DC: failed to create tg!\n");
970 goto res_create_fail;
971 }
972
973 pool->base.mis[i] = dce100_mem_input_create(ctx, i);
974 if (pool->base.mis[i] == NULL) {
975 BREAK_TO_DEBUGGER();
976 dm_error(
977 "DC: failed to create memory input!\n");
978 goto res_create_fail;
979 }
980
981 pool->base.ipps[i] = dce100_ipp_create(ctx, i);
982 if (pool->base.ipps[i] == NULL) {
983 BREAK_TO_DEBUGGER();
984 dm_error(
985 "DC: failed to create input pixel processor!\n");
986 goto res_create_fail;
987 }
988
989 pool->base.transforms[i] = dce100_transform_create(ctx, i);
990 if (pool->base.transforms[i] == NULL) {
991 BREAK_TO_DEBUGGER();
992 dm_error(
993 "DC: failed to create transform!\n");
994 goto res_create_fail;
995 }
996
997 pool->base.opps[i] = dce100_opp_create(ctx, i);
998 if (pool->base.opps[i] == NULL) {
999 BREAK_TO_DEBUGGER();
1000 dm_error(
1001 "DC: failed to create output pixel processor!\n");
1002 goto res_create_fail;
1003 }
1004 }
1005
1006 for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1007 pool->base.engines[i] = dce100_aux_engine_create(ctx, i);
1008 if (pool->base.engines[i] == NULL) {
1009 BREAK_TO_DEBUGGER();
1010 dm_error(
1011 "DC:failed to create aux engine!!\n");
1012 goto res_create_fail;
1013 }
1014 pool->base.hw_i2cs[i] = dce100_i2c_hw_create(ctx, i);
1015 if (pool->base.hw_i2cs[i] == NULL) {
1016 BREAK_TO_DEBUGGER();
1017 dm_error(
1018 "DC:failed to create i2c engine!!\n");
1019 goto res_create_fail;
1020 }
1021 pool->base.sw_i2cs[i] = NULL;
1022 }
1023
1024 dc->caps.max_planes = pool->base.pipe_count;
1025
1026 if (!resource_construct(num_virtual_links, dc, &pool->base,
1027 &res_create_funcs))
1028 goto res_create_fail;
1029
1030
1031 dce100_hw_sequencer_construct(dc);
1032 return true;
1033
1034res_create_fail:
1035 destruct(pool);
1036
1037 return false;
1038}
1039
1040struct resource_pool *dce100_create_resource_pool(
1041 uint8_t num_virtual_links,
1042 struct dc *dc)
1043{
1044 struct dce110_resource_pool *pool =
1045 kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
1046
1047 if (!pool)
1048 return NULL;
1049
1050 if (construct(num_virtual_links, dc, pool))
1051 return &pool->base;
1052
1053 BREAK_TO_DEBUGGER();
1054 return NULL;
1055}
1056
1057