318e9c2e2ca88c56f03c68099cd1a6bc71393736
[linux-2.6-block.git] / drivers / gpu / drm / amd / display / dc / dce110 / dce110_resource.c
1 /*
2  * Copyright 2012-15 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25
26 #include <linux/slab.h>
27
28 #include "dm_services.h"
29
30 #include "link_encoder.h"
31 #include "stream_encoder.h"
32
33 #include "resource.h"
34 #include "dce110/dce110_resource.h"
35 #include "include/irq_service_interface.h"
36 #include "dce/dce_audio.h"
37 #include "dce110/dce110_timing_generator.h"
38 #include "irq/dce110/irq_service_dce110.h"
39 #include "dce110/dce110_timing_generator_v.h"
40 #include "dce/dce_link_encoder.h"
41 #include "dce/dce_stream_encoder.h"
42 #include "dce/dce_mem_input.h"
43 #include "dce110/dce110_mem_input_v.h"
44 #include "dce/dce_ipp.h"
45 #include "dce/dce_transform.h"
46 #include "dce110/dce110_transform_v.h"
47 #include "dce/dce_opp.h"
48 #include "dce110/dce110_opp_v.h"
49 #include "dce/dce_clock_source.h"
50 #include "dce/dce_hwseq.h"
51 #include "dce110/dce110_hw_sequencer.h"
52 #include "dce/dce_aux.h"
53 #include "dce/dce_abm.h"
54 #include "dce/dce_dmcu.h"
55 #include "dce/dce_i2c.h"
56
57 #define DC_LOGGER \
58                 dc->ctx->logger
59
60 #include "dce110/dce110_compressor.h"
61
62 #include "reg_helper.h"
63
64 #include "dce/dce_11_0_d.h"
65 #include "dce/dce_11_0_sh_mask.h"
66
67 #ifndef mmMC_HUB_RDREQ_DMIF_LIMIT
68 #include "gmc/gmc_8_2_d.h"
69 #include "gmc/gmc_8_2_sh_mask.h"
70 #endif
71
72 #ifndef mmDP_DPHY_INTERNAL_CTRL
73         #define mmDP_DPHY_INTERNAL_CTRL 0x4aa7
74         #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x4aa7
75         #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x4ba7
76         #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x4ca7
77         #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x4da7
78         #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x4ea7
79         #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x4fa7
80         #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x54a7
81         #define mmDP7_DP_DPHY_INTERNAL_CTRL 0x56a7
82         #define mmDP8_DP_DPHY_INTERNAL_CTRL 0x57a7
83 #endif
84
85 #ifndef mmBIOS_SCRATCH_2
86         #define mmBIOS_SCRATCH_2 0x05CB
87         #define mmBIOS_SCRATCH_3 0x05CC
88         #define mmBIOS_SCRATCH_6 0x05CF
89 #endif
90
91 #ifndef mmDP_DPHY_BS_SR_SWAP_CNTL
92         #define mmDP_DPHY_BS_SR_SWAP_CNTL                       0x4ADC
93         #define mmDP0_DP_DPHY_BS_SR_SWAP_CNTL                   0x4ADC
94         #define mmDP1_DP_DPHY_BS_SR_SWAP_CNTL                   0x4BDC
95         #define mmDP2_DP_DPHY_BS_SR_SWAP_CNTL                   0x4CDC
96         #define mmDP3_DP_DPHY_BS_SR_SWAP_CNTL                   0x4DDC
97         #define mmDP4_DP_DPHY_BS_SR_SWAP_CNTL                   0x4EDC
98         #define mmDP5_DP_DPHY_BS_SR_SWAP_CNTL                   0x4FDC
99         #define mmDP6_DP_DPHY_BS_SR_SWAP_CNTL                   0x54DC
100 #endif
101
102 #ifndef mmDP_DPHY_FAST_TRAINING
103         #define mmDP_DPHY_FAST_TRAINING                         0x4ABC
104         #define mmDP0_DP_DPHY_FAST_TRAINING                     0x4ABC
105         #define mmDP1_DP_DPHY_FAST_TRAINING                     0x4BBC
106         #define mmDP2_DP_DPHY_FAST_TRAINING                     0x4CBC
107         #define mmDP3_DP_DPHY_FAST_TRAINING                     0x4DBC
108         #define mmDP4_DP_DPHY_FAST_TRAINING                     0x4EBC
109         #define mmDP5_DP_DPHY_FAST_TRAINING                     0x4FBC
110         #define mmDP6_DP_DPHY_FAST_TRAINING                     0x54BC
111 #endif
112
113 #ifndef DPHY_RX_FAST_TRAINING_CAPABLE
114         #define DPHY_RX_FAST_TRAINING_CAPABLE 0x1
115 #endif
116
117 static const struct dce110_timing_generator_offsets dce110_tg_offsets[] = {
118         {
119                 .crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL),
120                 .dcp =  (mmDCP0_GRPH_CONTROL - mmGRPH_CONTROL),
121         },
122         {
123                 .crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL),
124                 .dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL),
125         },
126         {
127                 .crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL),
128                 .dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL),
129         },
130         {
131                 .crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL),
132                 .dcp =  (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL),
133         },
134         {
135                 .crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL),
136                 .dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL),
137         },
138         {
139                 .crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL),
140                 .dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL),
141         }
142 };
143
144 /* set register offset */
145 #define SR(reg_name)\
146         .reg_name = mm ## reg_name
147
148 /* set register offset with instance */
149 #define SRI(reg_name, block, id)\
150         .reg_name = mm ## block ## id ## _ ## reg_name
151
152 static const struct dce_dmcu_registers dmcu_regs = {
153                 DMCU_DCE110_COMMON_REG_LIST()
154 };
155
156 static const struct dce_dmcu_shift dmcu_shift = {
157                 DMCU_MASK_SH_LIST_DCE110(__SHIFT)
158 };
159
160 static const struct dce_dmcu_mask dmcu_mask = {
161                 DMCU_MASK_SH_LIST_DCE110(_MASK)
162 };
163
164 static const struct dce_abm_registers abm_regs = {
165                 ABM_DCE110_COMMON_REG_LIST()
166 };
167
168 static const struct dce_abm_shift abm_shift = {
169                 ABM_MASK_SH_LIST_DCE110(__SHIFT)
170 };
171
172 static const struct dce_abm_mask abm_mask = {
173                 ABM_MASK_SH_LIST_DCE110(_MASK)
174 };
175
176 #define ipp_regs(id)\
177 [id] = {\
178                 IPP_DCE110_REG_LIST_DCE_BASE(id)\
179 }
180
181 static const struct dce_ipp_registers ipp_regs[] = {
182                 ipp_regs(0),
183                 ipp_regs(1),
184                 ipp_regs(2)
185 };
186
187 static const struct dce_ipp_shift ipp_shift = {
188                 IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
189 };
190
191 static const struct dce_ipp_mask ipp_mask = {
192                 IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
193 };
194
195 #define transform_regs(id)\
196 [id] = {\
197                 XFM_COMMON_REG_LIST_DCE110(id)\
198 }
199
200 static const struct dce_transform_registers xfm_regs[] = {
201                 transform_regs(0),
202                 transform_regs(1),
203                 transform_regs(2)
204 };
205
206 static const struct dce_transform_shift xfm_shift = {
207                 XFM_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
208 };
209
210 static const struct dce_transform_mask xfm_mask = {
211                 XFM_COMMON_MASK_SH_LIST_DCE110(_MASK)
212 };
213
214 #define aux_regs(id)\
215 [id] = {\
216         AUX_REG_LIST(id)\
217 }
218
219 static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
220                 aux_regs(0),
221                 aux_regs(1),
222                 aux_regs(2),
223                 aux_regs(3),
224                 aux_regs(4),
225                 aux_regs(5)
226 };
227
228 #define hpd_regs(id)\
229 [id] = {\
230         HPD_REG_LIST(id)\
231 }
232
233 static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
234                 hpd_regs(0),
235                 hpd_regs(1),
236                 hpd_regs(2),
237                 hpd_regs(3),
238                 hpd_regs(4),
239                 hpd_regs(5)
240 };
241
242
243 #define link_regs(id)\
244 [id] = {\
245         LE_DCE110_REG_LIST(id)\
246 }
247
248 static const struct dce110_link_enc_registers link_enc_regs[] = {
249         link_regs(0),
250         link_regs(1),
251         link_regs(2),
252         link_regs(3),
253         link_regs(4),
254         link_regs(5),
255         link_regs(6),
256 };
257
258 #define stream_enc_regs(id)\
259 [id] = {\
260         SE_COMMON_REG_LIST(id),\
261         .TMDS_CNTL = 0,\
262 }
263
264 static const struct dce110_stream_enc_registers stream_enc_regs[] = {
265         stream_enc_regs(0),
266         stream_enc_regs(1),
267         stream_enc_regs(2)
268 };
269
270 static const struct dce_stream_encoder_shift se_shift = {
271                 SE_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
272 };
273
274 static const struct dce_stream_encoder_mask se_mask = {
275                 SE_COMMON_MASK_SH_LIST_DCE110(_MASK)
276 };
277
278 #define opp_regs(id)\
279 [id] = {\
280         OPP_DCE_110_REG_LIST(id),\
281 }
282
283 static const struct dce_opp_registers opp_regs[] = {
284         opp_regs(0),
285         opp_regs(1),
286         opp_regs(2),
287         opp_regs(3),
288         opp_regs(4),
289         opp_regs(5)
290 };
291
292 static const struct dce_opp_shift opp_shift = {
293         OPP_COMMON_MASK_SH_LIST_DCE_110(__SHIFT)
294 };
295
296 static const struct dce_opp_mask opp_mask = {
297         OPP_COMMON_MASK_SH_LIST_DCE_110(_MASK)
298 };
299
300 #define aux_engine_regs(id)\
301 [id] = {\
302         AUX_COMMON_REG_LIST(id), \
303         .AUX_RESET_MASK = 0 \
304 }
305
306 static const struct dce110_aux_registers aux_engine_regs[] = {
307                 aux_engine_regs(0),
308                 aux_engine_regs(1),
309                 aux_engine_regs(2),
310                 aux_engine_regs(3),
311                 aux_engine_regs(4),
312                 aux_engine_regs(5)
313 };
314
315 #define audio_regs(id)\
316 [id] = {\
317         AUD_COMMON_REG_LIST(id)\
318 }
319
320 static const struct dce_audio_registers audio_regs[] = {
321         audio_regs(0),
322         audio_regs(1),
323         audio_regs(2),
324         audio_regs(3),
325         audio_regs(4),
326         audio_regs(5),
327         audio_regs(6),
328 };
329
330 static const struct dce_audio_shift audio_shift = {
331                 AUD_COMMON_MASK_SH_LIST(__SHIFT)
332 };
333
334 static const struct dce_audio_mask audio_mask = {
335                 AUD_COMMON_MASK_SH_LIST(_MASK)
336 };
337
338 /* AG TBD Needs to be reduced back to 3 pipes once dce10 hw sequencer implemented. */
339
340
341 #define clk_src_regs(id)\
342 [id] = {\
343         CS_COMMON_REG_LIST_DCE_100_110(id),\
344 }
345
346 static const struct dce110_clk_src_regs clk_src_regs[] = {
347         clk_src_regs(0),
348         clk_src_regs(1),
349         clk_src_regs(2)
350 };
351
352 static const struct dce110_clk_src_shift cs_shift = {
353                 CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
354 };
355
356 static const struct dce110_clk_src_mask cs_mask = {
357                 CS_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
358 };
359
360 static const struct bios_registers bios_regs = {
361         .BIOS_SCRATCH_3 = mmBIOS_SCRATCH_3,
362         .BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6
363 };
364
365 static const struct resource_caps carrizo_resource_cap = {
366                 .num_timing_generator = 3,
367                 .num_video_plane = 1,
368                 .num_audio = 3,
369                 .num_stream_encoder = 3,
370                 .num_pll = 2,
371                 .num_ddc = 3,
372 };
373
374 static const struct resource_caps stoney_resource_cap = {
375                 .num_timing_generator = 2,
376                 .num_video_plane = 1,
377                 .num_audio = 3,
378                 .num_stream_encoder = 3,
379                 .num_pll = 2,
380                 .num_ddc = 3,
381 };
382
383 static const struct dc_plane_cap plane_cap = {
384                 .type = DC_PLANE_TYPE_DCE_RGB,
385                 .blends_with_below = true,
386                 .blends_with_above = true,
387                 .per_pixel_alpha = 1,
388
389                 .pixel_format_support = {
390                                 .argb8888 = true,
391                                 .nv12 = false,
392                                 .fp16 = false
393                 },
394
395                 .max_upscale_factor = {
396                                 .argb8888 = 16000,
397                                 .nv12 = 1,
398                                 .fp16 = 1
399                 },
400
401                 .max_downscale_factor = {
402                                 .argb8888 = 250,
403                                 .nv12 = 1,
404                                 .fp16 = 1
405                 }
406 };
407
408 static const struct dc_plane_cap underlay_plane_cap = {
409                 .type = DC_PLANE_TYPE_DCE_UNDERLAY,
410                 .blends_with_above = true,
411                 .per_pixel_alpha = 1,
412
413                 .pixel_format_support = {
414                                 .argb8888 = false,
415                                 .nv12 = true,
416                                 .fp16 = false
417                 },
418
419                 .max_upscale_factor = {
420                                 .argb8888 = 1,
421                                 .nv12 = 16000,
422                                 .fp16 = 1
423                 },
424
425                 .max_downscale_factor = {
426                                 .argb8888 = 1,
427                                 .nv12 = 250,
428                                 .fp16 = 1
429                 }
430 };
431
432 #define CTX  ctx
433 #define REG(reg) mm ## reg
434
435 #ifndef mmCC_DC_HDMI_STRAPS
436 #define mmCC_DC_HDMI_STRAPS 0x4819
437 #define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40
438 #define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6
439 #define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700
440 #define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
441 #endif
442
443 static void read_dce_straps(
444         struct dc_context *ctx,
445         struct resource_straps *straps)
446 {
447         REG_GET_2(CC_DC_HDMI_STRAPS,
448                         HDMI_DISABLE, &straps->hdmi_disable,
449                         AUDIO_STREAM_NUMBER, &straps->audio_stream_number);
450
451         REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio);
452 }
453
454 static struct audio *create_audio(
455                 struct dc_context *ctx, unsigned int inst)
456 {
457         return dce_audio_create(ctx, inst,
458                         &audio_regs[inst], &audio_shift, &audio_mask);
459 }
460
461 static struct timing_generator *dce110_timing_generator_create(
462                 struct dc_context *ctx,
463                 uint32_t instance,
464                 const struct dce110_timing_generator_offsets *offsets)
465 {
466         struct dce110_timing_generator *tg110 =
467                 kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL);
468
469         if (!tg110)
470                 return NULL;
471
472         dce110_timing_generator_construct(tg110, ctx, instance, offsets);
473         return &tg110->base;
474 }
475
476 static struct stream_encoder *dce110_stream_encoder_create(
477         enum engine_id eng_id,
478         struct dc_context *ctx)
479 {
480         struct dce110_stream_encoder *enc110 =
481                 kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL);
482
483         if (!enc110)
484                 return NULL;
485
486         dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
487                                         &stream_enc_regs[eng_id],
488                                         &se_shift, &se_mask);
489         return &enc110->base;
490 }
491
492 #define SRII(reg_name, block, id)\
493         .reg_name[id] = mm ## block ## id ## _ ## reg_name
494
495 static const struct dce_hwseq_registers hwseq_stoney_reg = {
496                 HWSEQ_ST_REG_LIST()
497 };
498
499 static const struct dce_hwseq_registers hwseq_cz_reg = {
500                 HWSEQ_CZ_REG_LIST()
501 };
502
503 static const struct dce_hwseq_shift hwseq_shift = {
504                 HWSEQ_DCE11_MASK_SH_LIST(__SHIFT),
505 };
506
507 static const struct dce_hwseq_mask hwseq_mask = {
508                 HWSEQ_DCE11_MASK_SH_LIST(_MASK),
509 };
510
511 static struct dce_hwseq *dce110_hwseq_create(
512         struct dc_context *ctx)
513 {
514         struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
515
516         if (hws) {
517                 hws->ctx = ctx;
518                 hws->regs = ASIC_REV_IS_STONEY(ctx->asic_id.hw_internal_rev) ?
519                                 &hwseq_stoney_reg : &hwseq_cz_reg;
520                 hws->shifts = &hwseq_shift;
521                 hws->masks = &hwseq_mask;
522                 hws->wa.blnd_crtc_trigger = true;
523         }
524         return hws;
525 }
526
527 static const struct resource_create_funcs res_create_funcs = {
528         .read_dce_straps = read_dce_straps,
529         .create_audio = create_audio,
530         .create_stream_encoder = dce110_stream_encoder_create,
531         .create_hwseq = dce110_hwseq_create,
532 };
533
534 #define mi_inst_regs(id) { \
535         MI_DCE11_REG_LIST(id), \
536         .MC_HUB_RDREQ_DMIF_LIMIT = mmMC_HUB_RDREQ_DMIF_LIMIT \
537 }
538 static const struct dce_mem_input_registers mi_regs[] = {
539                 mi_inst_regs(0),
540                 mi_inst_regs(1),
541                 mi_inst_regs(2),
542 };
543
544 static const struct dce_mem_input_shift mi_shifts = {
545                 MI_DCE11_MASK_SH_LIST(__SHIFT),
546                 .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE__SHIFT
547 };
548
549 static const struct dce_mem_input_mask mi_masks = {
550                 MI_DCE11_MASK_SH_LIST(_MASK),
551                 .ENABLE = MC_HUB_RDREQ_DMIF_LIMIT__ENABLE_MASK
552 };
553
554
555 static struct mem_input *dce110_mem_input_create(
556         struct dc_context *ctx,
557         uint32_t inst)
558 {
559         struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input),
560                                                GFP_KERNEL);
561
562         if (!dce_mi) {
563                 BREAK_TO_DEBUGGER();
564                 return NULL;
565         }
566
567         dce_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks);
568         dce_mi->wa.single_head_rdreq_dmif_limit = 3;
569         return &dce_mi->base;
570 }
571
572 static void dce110_transform_destroy(struct transform **xfm)
573 {
574         kfree(TO_DCE_TRANSFORM(*xfm));
575         *xfm = NULL;
576 }
577
578 static struct transform *dce110_transform_create(
579         struct dc_context *ctx,
580         uint32_t inst)
581 {
582         struct dce_transform *transform =
583                 kzalloc(sizeof(struct dce_transform), GFP_KERNEL);
584
585         if (!transform)
586                 return NULL;
587
588         dce_transform_construct(transform, ctx, inst,
589                                 &xfm_regs[inst], &xfm_shift, &xfm_mask);
590         return &transform->base;
591 }
592
593 static struct input_pixel_processor *dce110_ipp_create(
594         struct dc_context *ctx, uint32_t inst)
595 {
596         struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL);
597
598         if (!ipp) {
599                 BREAK_TO_DEBUGGER();
600                 return NULL;
601         }
602
603         dce_ipp_construct(ipp, ctx, inst,
604                         &ipp_regs[inst], &ipp_shift, &ipp_mask);
605         return &ipp->base;
606 }
607
608 static const struct encoder_feature_support link_enc_feature = {
609                 .max_hdmi_deep_color = COLOR_DEPTH_121212,
610                 .max_hdmi_pixel_clock = 300000,
611                 .flags.bits.IS_HBR2_CAPABLE = true,
612                 .flags.bits.IS_TPS3_CAPABLE = true
613 };
614
615 static struct link_encoder *dce110_link_encoder_create(
616         const struct encoder_init_data *enc_init_data)
617 {
618         struct dce110_link_encoder *enc110 =
619                 kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
620
621         if (!enc110)
622                 return NULL;
623
624         dce110_link_encoder_construct(enc110,
625                                       enc_init_data,
626                                       &link_enc_feature,
627                                       &link_enc_regs[enc_init_data->transmitter],
628                                       &link_enc_aux_regs[enc_init_data->channel - 1],
629                                       &link_enc_hpd_regs[enc_init_data->hpd_source]);
630         return &enc110->base;
631 }
632
633 static struct output_pixel_processor *dce110_opp_create(
634         struct dc_context *ctx,
635         uint32_t inst)
636 {
637         struct dce110_opp *opp =
638                 kzalloc(sizeof(struct dce110_opp), GFP_KERNEL);
639
640         if (!opp)
641                 return NULL;
642
643         dce110_opp_construct(opp,
644                              ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask);
645         return &opp->base;
646 }
647
648 struct dce_aux *dce110_aux_engine_create(
649         struct dc_context *ctx,
650         uint32_t inst)
651 {
652         struct aux_engine_dce110 *aux_engine =
653                 kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
654
655         if (!aux_engine)
656                 return NULL;
657
658         dce110_aux_engine_construct(aux_engine, ctx, inst,
659                                     SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD,
660                                     &aux_engine_regs[inst]);
661
662         return &aux_engine->base;
663 }
664 #define i2c_inst_regs(id) { I2C_HW_ENGINE_COMMON_REG_LIST(id) }
665
666 static const struct dce_i2c_registers i2c_hw_regs[] = {
667                 i2c_inst_regs(1),
668                 i2c_inst_regs(2),
669                 i2c_inst_regs(3),
670                 i2c_inst_regs(4),
671                 i2c_inst_regs(5),
672                 i2c_inst_regs(6),
673 };
674
675 static const struct dce_i2c_shift i2c_shifts = {
676                 I2C_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
677 };
678
679 static const struct dce_i2c_mask i2c_masks = {
680                 I2C_COMMON_MASK_SH_LIST_DCE110(_MASK)
681 };
682
683 struct dce_i2c_hw *dce110_i2c_hw_create(
684         struct dc_context *ctx,
685         uint32_t inst)
686 {
687         struct dce_i2c_hw *dce_i2c_hw =
688                 kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
689
690         if (!dce_i2c_hw)
691                 return NULL;
692
693         dce100_i2c_hw_construct(dce_i2c_hw, ctx, inst,
694                                     &i2c_hw_regs[inst], &i2c_shifts, &i2c_masks);
695
696         return dce_i2c_hw;
697 }
698 struct clock_source *dce110_clock_source_create(
699         struct dc_context *ctx,
700         struct dc_bios *bios,
701         enum clock_source_id id,
702         const struct dce110_clk_src_regs *regs,
703         bool dp_clk_src)
704 {
705         struct dce110_clk_src *clk_src =
706                 kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
707
708         if (!clk_src)
709                 return NULL;
710
711         if (dce110_clk_src_construct(clk_src, ctx, bios, id,
712                         regs, &cs_shift, &cs_mask)) {
713                 clk_src->base.dp_clk_src = dp_clk_src;
714                 return &clk_src->base;
715         }
716
717         BREAK_TO_DEBUGGER();
718         return NULL;
719 }
720
721 void dce110_clock_source_destroy(struct clock_source **clk_src)
722 {
723         struct dce110_clk_src *dce110_clk_src;
724
725         if (!clk_src)
726                 return;
727
728         dce110_clk_src = TO_DCE110_CLK_SRC(*clk_src);
729
730         kfree(dce110_clk_src->dp_ss_params);
731         kfree(dce110_clk_src->hdmi_ss_params);
732         kfree(dce110_clk_src->dvi_ss_params);
733
734         kfree(dce110_clk_src);
735         *clk_src = NULL;
736 }
737
738 static void destruct(struct dce110_resource_pool *pool)
739 {
740         unsigned int i;
741
742         for (i = 0; i < pool->base.pipe_count; i++) {
743                 if (pool->base.opps[i] != NULL)
744                         dce110_opp_destroy(&pool->base.opps[i]);
745
746                 if (pool->base.transforms[i] != NULL)
747                         dce110_transform_destroy(&pool->base.transforms[i]);
748
749                 if (pool->base.ipps[i] != NULL)
750                         dce_ipp_destroy(&pool->base.ipps[i]);
751
752                 if (pool->base.mis[i] != NULL) {
753                         kfree(TO_DCE_MEM_INPUT(pool->base.mis[i]));
754                         pool->base.mis[i] = NULL;
755                 }
756
757                 if (pool->base.timing_generators[i] != NULL)    {
758                         kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i]));
759                         pool->base.timing_generators[i] = NULL;
760                 }
761         }
762
763         for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
764                 if (pool->base.engines[i] != NULL)
765                         dce110_engine_destroy(&pool->base.engines[i]);
766                 if (pool->base.hw_i2cs[i] != NULL) {
767                         kfree(pool->base.hw_i2cs[i]);
768                         pool->base.hw_i2cs[i] = NULL;
769                 }
770                 if (pool->base.sw_i2cs[i] != NULL) {
771                         kfree(pool->base.sw_i2cs[i]);
772                         pool->base.sw_i2cs[i] = NULL;
773                 }
774         }
775
776         for (i = 0; i < pool->base.stream_enc_count; i++) {
777                 if (pool->base.stream_enc[i] != NULL)
778                         kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));
779         }
780
781         for (i = 0; i < pool->base.clk_src_count; i++) {
782                 if (pool->base.clock_sources[i] != NULL) {
783                         dce110_clock_source_destroy(&pool->base.clock_sources[i]);
784                 }
785         }
786
787         if (pool->base.dp_clock_source != NULL)
788                 dce110_clock_source_destroy(&pool->base.dp_clock_source);
789
790         for (i = 0; i < pool->base.audio_count; i++)    {
791                 if (pool->base.audios[i] != NULL) {
792                         dce_aud_destroy(&pool->base.audios[i]);
793                 }
794         }
795
796         if (pool->base.abm != NULL)
797                 dce_abm_destroy(&pool->base.abm);
798
799         if (pool->base.dmcu != NULL)
800                 dce_dmcu_destroy(&pool->base.dmcu);
801
802         if (pool->base.irqs != NULL) {
803                 dal_irq_service_destroy(&pool->base.irqs);
804         }
805 }
806
807
808 static void get_pixel_clock_parameters(
809         const struct pipe_ctx *pipe_ctx,
810         struct pixel_clk_params *pixel_clk_params)
811 {
812         const struct dc_stream_state *stream = pipe_ctx->stream;
813
814         /*TODO: is this halved for YCbCr 420? in that case we might want to move
815          * the pixel clock normalization for hdmi up to here instead of doing it
816          * in pll_adjust_pix_clk
817          */
818         pixel_clk_params->requested_pix_clk_100hz = stream->timing.pix_clk_100hz;
819         pixel_clk_params->encoder_object_id = stream->link->link_enc->id;
820         pixel_clk_params->signal_type = pipe_ctx->stream->signal;
821         pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1;
822         /* TODO: un-hardcode*/
823         pixel_clk_params->requested_sym_clk = LINK_RATE_LOW *
824                                                 LINK_RATE_REF_FREQ_IN_KHZ;
825         pixel_clk_params->flags.ENABLE_SS = 0;
826         pixel_clk_params->color_depth =
827                 stream->timing.display_color_depth;
828         pixel_clk_params->flags.DISPLAY_BLANKED = 1;
829         pixel_clk_params->flags.SUPPORT_YCBCR420 = (stream->timing.pixel_encoding ==
830                         PIXEL_ENCODING_YCBCR420);
831         pixel_clk_params->pixel_encoding = stream->timing.pixel_encoding;
832         if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422) {
833                 pixel_clk_params->color_depth = COLOR_DEPTH_888;
834         }
835         if (stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) {
836                 pixel_clk_params->requested_pix_clk_100hz  = pixel_clk_params->requested_pix_clk_100hz / 2;
837         }
838         if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING)
839                 pixel_clk_params->requested_pix_clk_100hz *= 2;
840
841 }
842
843 void dce110_resource_build_pipe_hw_param(struct pipe_ctx *pipe_ctx)
844 {
845         get_pixel_clock_parameters(pipe_ctx, &pipe_ctx->stream_res.pix_clk_params);
846         pipe_ctx->clock_source->funcs->get_pix_clk_dividers(
847                 pipe_ctx->clock_source,
848                 &pipe_ctx->stream_res.pix_clk_params,
849                 &pipe_ctx->pll_settings);
850         resource_build_bit_depth_reduction_params(pipe_ctx->stream,
851                         &pipe_ctx->stream->bit_depth_params);
852         pipe_ctx->stream->clamping.pixel_encoding = pipe_ctx->stream->timing.pixel_encoding;
853 }
854
855 static bool is_surface_pixel_format_supported(struct pipe_ctx *pipe_ctx, unsigned int underlay_idx)
856 {
857         if (pipe_ctx->pipe_idx != underlay_idx)
858                 return true;
859         if (!pipe_ctx->plane_state)
860                 return false;
861         if (pipe_ctx->plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
862                 return false;
863         return true;
864 }
865
866 static enum dc_status build_mapped_resource(
867                 const struct dc *dc,
868                 struct dc_state *context,
869                 struct dc_stream_state *stream)
870 {
871         struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream);
872
873         if (!pipe_ctx)
874                 return DC_ERROR_UNEXPECTED;
875
876         if (!is_surface_pixel_format_supported(pipe_ctx,
877                         dc->res_pool->underlay_pipe_index))
878                 return DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED;
879
880         dce110_resource_build_pipe_hw_param(pipe_ctx);
881
882         /* TODO: validate audio ASIC caps, encoder */
883
884         resource_build_info_frame(pipe_ctx);
885
886         return DC_OK;
887 }
888
889 static bool dce110_validate_bandwidth(
890         struct dc *dc,
891         struct dc_state *context,
892         bool fast_validate)
893 {
894         bool result = false;
895
896         DC_LOG_BANDWIDTH_CALCS(
897                 "%s: start",
898                 __func__);
899
900         if (bw_calcs(
901                         dc->ctx,
902                         dc->bw_dceip,
903                         dc->bw_vbios,
904                         context->res_ctx.pipe_ctx,
905                         dc->res_pool->pipe_count,
906                         &context->bw_ctx.bw.dce))
907                 result =  true;
908
909         if (!result)
910                 DC_LOG_BANDWIDTH_VALIDATION("%s: %dx%d@%d Bandwidth validation failed!\n",
911                         __func__,
912                         context->streams[0]->timing.h_addressable,
913                         context->streams[0]->timing.v_addressable,
914                         context->streams[0]->timing.pix_clk_100hz / 10);
915
916         if (memcmp(&dc->current_state->bw_ctx.bw.dce,
917                         &context->bw_ctx.bw.dce, sizeof(context->bw_ctx.bw.dce))) {
918
919                 DC_LOG_BANDWIDTH_CALCS(
920                         "%s: finish,\n"
921                         "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
922                         "stutMark_b: %d stutMark_a: %d\n"
923                         "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
924                         "stutMark_b: %d stutMark_a: %d\n"
925                         "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
926                         "stutMark_b: %d stutMark_a: %d stutter_mode_enable: %d\n"
927                         "cstate: %d pstate: %d nbpstate: %d sync: %d dispclk: %d\n"
928                         "sclk: %d sclk_sleep: %d yclk: %d blackout_recovery_time_us: %d\n"
929                         ,
930                         __func__,
931                         context->bw_ctx.bw.dce.nbp_state_change_wm_ns[0].b_mark,
932                         context->bw_ctx.bw.dce.nbp_state_change_wm_ns[0].a_mark,
933                         context->bw_ctx.bw.dce.urgent_wm_ns[0].b_mark,
934                         context->bw_ctx.bw.dce.urgent_wm_ns[0].a_mark,
935                         context->bw_ctx.bw.dce.stutter_exit_wm_ns[0].b_mark,
936                         context->bw_ctx.bw.dce.stutter_exit_wm_ns[0].a_mark,
937                         context->bw_ctx.bw.dce.nbp_state_change_wm_ns[1].b_mark,
938                         context->bw_ctx.bw.dce.nbp_state_change_wm_ns[1].a_mark,
939                         context->bw_ctx.bw.dce.urgent_wm_ns[1].b_mark,
940                         context->bw_ctx.bw.dce.urgent_wm_ns[1].a_mark,
941                         context->bw_ctx.bw.dce.stutter_exit_wm_ns[1].b_mark,
942                         context->bw_ctx.bw.dce.stutter_exit_wm_ns[1].a_mark,
943                         context->bw_ctx.bw.dce.nbp_state_change_wm_ns[2].b_mark,
944                         context->bw_ctx.bw.dce.nbp_state_change_wm_ns[2].a_mark,
945                         context->bw_ctx.bw.dce.urgent_wm_ns[2].b_mark,
946                         context->bw_ctx.bw.dce.urgent_wm_ns[2].a_mark,
947                         context->bw_ctx.bw.dce.stutter_exit_wm_ns[2].b_mark,
948                         context->bw_ctx.bw.dce.stutter_exit_wm_ns[2].a_mark,
949                         context->bw_ctx.bw.dce.stutter_mode_enable,
950                         context->bw_ctx.bw.dce.cpuc_state_change_enable,
951                         context->bw_ctx.bw.dce.cpup_state_change_enable,
952                         context->bw_ctx.bw.dce.nbp_state_change_enable,
953                         context->bw_ctx.bw.dce.all_displays_in_sync,
954                         context->bw_ctx.bw.dce.dispclk_khz,
955                         context->bw_ctx.bw.dce.sclk_khz,
956                         context->bw_ctx.bw.dce.sclk_deep_sleep_khz,
957                         context->bw_ctx.bw.dce.yclk_khz,
958                         context->bw_ctx.bw.dce.blackout_recovery_time_us);
959         }
960         return result;
961 }
962
963 enum dc_status dce110_validate_plane(const struct dc_plane_state *plane_state,
964                                      struct dc_caps *caps)
965 {
966         if (((plane_state->dst_rect.width * 2) < plane_state->src_rect.width) ||
967             ((plane_state->dst_rect.height * 2) < plane_state->src_rect.height))
968                 return DC_FAIL_SURFACE_VALIDATE;
969
970         return DC_OK;
971 }
972
973 static bool dce110_validate_surface_sets(
974                 struct dc_state *context)
975 {
976         int i, j;
977
978         for (i = 0; i < context->stream_count; i++) {
979                 if (context->stream_status[i].plane_count == 0)
980                         continue;
981
982                 if (context->stream_status[i].plane_count > 2)
983                         return false;
984
985                 for (j = 0; j < context->stream_status[i].plane_count; j++) {
986                         struct dc_plane_state *plane =
987                                 context->stream_status[i].plane_states[j];
988
989                         /* underlay validation */
990                         if (plane->format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
991
992                                 if ((plane->src_rect.width > 1920 ||
993                                         plane->src_rect.height > 1080))
994                                         return false;
995
996                                 /* we don't have the logic to support underlay
997                                  * only yet so block the use case where we get
998                                  * NV12 plane as top layer
999                                  */
1000                                 if (j == 0)
1001                                         return false;
1002
1003                                 /* irrespective of plane format,
1004                                  * stream should be RGB encoded
1005                                  */
1006                                 if (context->streams[i]->timing.pixel_encoding
1007                                                 != PIXEL_ENCODING_RGB)
1008                                         return false;
1009
1010                         }
1011
1012                 }
1013         }
1014
1015         return true;
1016 }
1017
1018 enum dc_status dce110_validate_global(
1019                 struct dc *dc,
1020                 struct dc_state *context)
1021 {
1022         if (!dce110_validate_surface_sets(context))
1023                 return DC_FAIL_SURFACE_VALIDATE;
1024
1025         return DC_OK;
1026 }
1027
1028 static enum dc_status dce110_add_stream_to_ctx(
1029                 struct dc *dc,
1030                 struct dc_state *new_ctx,
1031                 struct dc_stream_state *dc_stream)
1032 {
1033         enum dc_status result = DC_ERROR_UNEXPECTED;
1034
1035         result = resource_map_pool_resources(dc, new_ctx, dc_stream);
1036
1037         if (result == DC_OK)
1038                 result = resource_map_clock_resources(dc, new_ctx, dc_stream);
1039
1040
1041         if (result == DC_OK)
1042                 result = build_mapped_resource(dc, new_ctx, dc_stream);
1043
1044         return result;
1045 }
1046
1047 static struct pipe_ctx *dce110_acquire_underlay(
1048                 struct dc_state *context,
1049                 const struct resource_pool *pool,
1050                 struct dc_stream_state *stream)
1051 {
1052         struct dc *dc = stream->ctx->dc;
1053         struct resource_context *res_ctx = &context->res_ctx;
1054         unsigned int underlay_idx = pool->underlay_pipe_index;
1055         struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[underlay_idx];
1056
1057         if (res_ctx->pipe_ctx[underlay_idx].stream)
1058                 return NULL;
1059
1060         pipe_ctx->stream_res.tg = pool->timing_generators[underlay_idx];
1061         pipe_ctx->plane_res.mi = pool->mis[underlay_idx];
1062         /*pipe_ctx->plane_res.ipp = res_ctx->pool->ipps[underlay_idx];*/
1063         pipe_ctx->plane_res.xfm = pool->transforms[underlay_idx];
1064         pipe_ctx->stream_res.opp = pool->opps[underlay_idx];
1065         pipe_ctx->pipe_idx = underlay_idx;
1066
1067         pipe_ctx->stream = stream;
1068
1069         if (!dc->current_state->res_ctx.pipe_ctx[underlay_idx].stream) {
1070                 struct tg_color black_color = {0};
1071                 struct dc_bios *dcb = dc->ctx->dc_bios;
1072
1073                 dc->hwss.enable_display_power_gating(
1074                                 dc,
1075                                 pipe_ctx->stream_res.tg->inst,
1076                                 dcb, PIPE_GATING_CONTROL_DISABLE);
1077
1078                 /*
1079                  * This is for powering on underlay, so crtc does not
1080                  * need to be enabled
1081                  */
1082
1083                 pipe_ctx->stream_res.tg->funcs->program_timing(pipe_ctx->stream_res.tg,
1084                                 &stream->timing,
1085                                 0,
1086                                 0,
1087                                 0,
1088                                 0,
1089                                 pipe_ctx->stream->signal,
1090                                 false);
1091
1092                 pipe_ctx->stream_res.tg->funcs->enable_advanced_request(
1093                                 pipe_ctx->stream_res.tg,
1094                                 true,
1095                                 &stream->timing);
1096
1097                 pipe_ctx->plane_res.mi->funcs->allocate_mem_input(pipe_ctx->plane_res.mi,
1098                                 stream->timing.h_total,
1099                                 stream->timing.v_total,
1100                                 stream->timing.pix_clk_100hz / 10,
1101                                 context->stream_count);
1102
1103                 color_space_to_black_color(dc,
1104                                 COLOR_SPACE_YCBCR601, &black_color);
1105                 pipe_ctx->stream_res.tg->funcs->set_blank_color(
1106                                 pipe_ctx->stream_res.tg,
1107                                 &black_color);
1108         }
1109
1110         return pipe_ctx;
1111 }
1112
1113 static void dce110_destroy_resource_pool(struct resource_pool **pool)
1114 {
1115         struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
1116
1117         destruct(dce110_pool);
1118         kfree(dce110_pool);
1119         *pool = NULL;
1120 }
1121
1122 struct stream_encoder *dce110_find_first_free_match_stream_enc_for_link(
1123                 struct resource_context *res_ctx,
1124                 const struct resource_pool *pool,
1125                 struct dc_stream_state *stream)
1126 {
1127         int i;
1128         int j = -1;
1129         struct dc_link *link = stream->link;
1130
1131         for (i = 0; i < pool->stream_enc_count; i++) {
1132                 if (!res_ctx->is_stream_enc_acquired[i] &&
1133                                 pool->stream_enc[i]) {
1134                         /* Store first available for MST second display
1135                          * in daisy chain use case
1136                          */
1137                         j = i;
1138                         if (pool->stream_enc[i]->id ==
1139                                         link->link_enc->preferred_engine)
1140                                 return pool->stream_enc[i];
1141                 }
1142         }
1143
1144         /*
1145          * For CZ and later, we can allow DIG FE and BE to differ for all display types
1146          */
1147
1148         if (j >= 0)
1149                 return pool->stream_enc[j];
1150
1151         return NULL;
1152 }
1153
1154
1155 static const struct resource_funcs dce110_res_pool_funcs = {
1156         .destroy = dce110_destroy_resource_pool,
1157         .link_enc_create = dce110_link_encoder_create,
1158         .validate_bandwidth = dce110_validate_bandwidth,
1159         .validate_plane = dce110_validate_plane,
1160         .acquire_idle_pipe_for_layer = dce110_acquire_underlay,
1161         .add_stream_to_ctx = dce110_add_stream_to_ctx,
1162         .validate_global = dce110_validate_global,
1163         .find_first_free_match_stream_enc_for_link = dce110_find_first_free_match_stream_enc_for_link
1164 };
1165
1166 static bool underlay_create(struct dc_context *ctx, struct resource_pool *pool)
1167 {
1168         struct dce110_timing_generator *dce110_tgv = kzalloc(sizeof(*dce110_tgv),
1169                                                              GFP_KERNEL);
1170         struct dce_transform *dce110_xfmv = kzalloc(sizeof(*dce110_xfmv),
1171                                                     GFP_KERNEL);
1172         struct dce_mem_input *dce110_miv = kzalloc(sizeof(*dce110_miv),
1173                                                    GFP_KERNEL);
1174         struct dce110_opp *dce110_oppv = kzalloc(sizeof(*dce110_oppv),
1175                                                  GFP_KERNEL);
1176
1177         if (!dce110_tgv || !dce110_xfmv || !dce110_miv || !dce110_oppv) {
1178                 kfree(dce110_tgv);
1179                 kfree(dce110_xfmv);
1180                 kfree(dce110_miv);
1181                 kfree(dce110_oppv);
1182                 return false;
1183         }
1184
1185         dce110_opp_v_construct(dce110_oppv, ctx);
1186
1187         dce110_timing_generator_v_construct(dce110_tgv, ctx);
1188         dce110_mem_input_v_construct(dce110_miv, ctx);
1189         dce110_transform_v_construct(dce110_xfmv, ctx);
1190
1191         pool->opps[pool->pipe_count] = &dce110_oppv->base;
1192         pool->timing_generators[pool->pipe_count] = &dce110_tgv->base;
1193         pool->mis[pool->pipe_count] = &dce110_miv->base;
1194         pool->transforms[pool->pipe_count] = &dce110_xfmv->base;
1195         pool->pipe_count++;
1196
1197         /* update the public caps to indicate an underlay is available */
1198         ctx->dc->caps.max_slave_planes = 1;
1199         ctx->dc->caps.max_slave_planes = 1;
1200
1201         return true;
1202 }
1203
1204 static void bw_calcs_data_update_from_pplib(struct dc *dc)
1205 {
1206         struct dm_pp_clock_levels clks = {0};
1207
1208         /*do system clock*/
1209         dm_pp_get_clock_levels_by_type(
1210                         dc->ctx,
1211                         DM_PP_CLOCK_TYPE_ENGINE_CLK,
1212                         &clks);
1213         /* convert all the clock fro kHz to fix point mHz */
1214         dc->bw_vbios->high_sclk = bw_frc_to_fixed(
1215                         clks.clocks_in_khz[clks.num_levels-1], 1000);
1216         dc->bw_vbios->mid1_sclk  = bw_frc_to_fixed(
1217                         clks.clocks_in_khz[clks.num_levels/8], 1000);
1218         dc->bw_vbios->mid2_sclk  = bw_frc_to_fixed(
1219                         clks.clocks_in_khz[clks.num_levels*2/8], 1000);
1220         dc->bw_vbios->mid3_sclk  = bw_frc_to_fixed(
1221                         clks.clocks_in_khz[clks.num_levels*3/8], 1000);
1222         dc->bw_vbios->mid4_sclk  = bw_frc_to_fixed(
1223                         clks.clocks_in_khz[clks.num_levels*4/8], 1000);
1224         dc->bw_vbios->mid5_sclk  = bw_frc_to_fixed(
1225                         clks.clocks_in_khz[clks.num_levels*5/8], 1000);
1226         dc->bw_vbios->mid6_sclk  = bw_frc_to_fixed(
1227                         clks.clocks_in_khz[clks.num_levels*6/8], 1000);
1228         dc->bw_vbios->low_sclk  = bw_frc_to_fixed(
1229                         clks.clocks_in_khz[0], 1000);
1230         dc->sclk_lvls = clks;
1231
1232         /*do display clock*/
1233         dm_pp_get_clock_levels_by_type(
1234                         dc->ctx,
1235                         DM_PP_CLOCK_TYPE_DISPLAY_CLK,
1236                         &clks);
1237         dc->bw_vbios->high_voltage_max_dispclk = bw_frc_to_fixed(
1238                         clks.clocks_in_khz[clks.num_levels-1], 1000);
1239         dc->bw_vbios->mid_voltage_max_dispclk  = bw_frc_to_fixed(
1240                         clks.clocks_in_khz[clks.num_levels>>1], 1000);
1241         dc->bw_vbios->low_voltage_max_dispclk  = bw_frc_to_fixed(
1242                         clks.clocks_in_khz[0], 1000);
1243
1244         /*do memory clock*/
1245         dm_pp_get_clock_levels_by_type(
1246                         dc->ctx,
1247                         DM_PP_CLOCK_TYPE_MEMORY_CLK,
1248                         &clks);
1249
1250         dc->bw_vbios->low_yclk = bw_frc_to_fixed(
1251                 clks.clocks_in_khz[0] * MEMORY_TYPE_MULTIPLIER_CZ, 1000);
1252         dc->bw_vbios->mid_yclk = bw_frc_to_fixed(
1253                 clks.clocks_in_khz[clks.num_levels>>1] * MEMORY_TYPE_MULTIPLIER_CZ,
1254                 1000);
1255         dc->bw_vbios->high_yclk = bw_frc_to_fixed(
1256                 clks.clocks_in_khz[clks.num_levels-1] * MEMORY_TYPE_MULTIPLIER_CZ,
1257                 1000);
1258 }
1259
1260 const struct resource_caps *dce110_resource_cap(
1261         struct hw_asic_id *asic_id)
1262 {
1263         if (ASIC_REV_IS_STONEY(asic_id->hw_internal_rev))
1264                 return &stoney_resource_cap;
1265         else
1266                 return &carrizo_resource_cap;
1267 }
1268
1269 static bool construct(
1270         uint8_t num_virtual_links,
1271         struct dc *dc,
1272         struct dce110_resource_pool *pool,
1273         struct hw_asic_id asic_id)
1274 {
1275         unsigned int i;
1276         struct dc_context *ctx = dc->ctx;
1277         struct dc_bios *bp;
1278
1279         ctx->dc_bios->regs = &bios_regs;
1280
1281         pool->base.res_cap = dce110_resource_cap(&ctx->asic_id);
1282         pool->base.funcs = &dce110_res_pool_funcs;
1283
1284         /*************************************************
1285          *  Resource + asic cap harcoding                *
1286          *************************************************/
1287
1288         pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
1289         pool->base.underlay_pipe_index = pool->base.pipe_count;
1290         pool->base.timing_generator_count = pool->base.res_cap->num_timing_generator;
1291         dc->caps.max_downscale_ratio = 150;
1292         dc->caps.i2c_speed_in_khz = 100;
1293         dc->caps.max_cursor_size = 128;
1294         dc->caps.is_apu = true;
1295
1296         /*************************************************
1297          *  Create resources                             *
1298          *************************************************/
1299
1300         bp = ctx->dc_bios;
1301
1302         if (bp->fw_info_valid && bp->fw_info.external_clock_source_frequency_for_dp != 0) {
1303                 pool->base.dp_clock_source =
1304                                 dce110_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_EXTERNAL, NULL, true);
1305
1306                 pool->base.clock_sources[0] =
1307                                 dce110_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL0,
1308                                                 &clk_src_regs[0], false);
1309                 pool->base.clock_sources[1] =
1310                                 dce110_clock_source_create(ctx, bp, CLOCK_SOURCE_ID_PLL1,
1311                                                 &clk_src_regs[1], false);
1312
1313                 pool->base.clk_src_count = 2;
1314
1315                 /* TODO: find out if CZ support 3 PLLs */
1316         }
1317
1318         if (pool->base.dp_clock_source == NULL) {
1319                 dm_error("DC: failed to create dp clock source!\n");
1320                 BREAK_TO_DEBUGGER();
1321                 goto res_create_fail;
1322         }
1323
1324         for (i = 0; i < pool->base.clk_src_count; i++) {
1325                 if (pool->base.clock_sources[i] == NULL) {
1326                         dm_error("DC: failed to create clock sources!\n");
1327                         BREAK_TO_DEBUGGER();
1328                         goto res_create_fail;
1329                 }
1330         }
1331
1332         pool->base.dmcu = dce_dmcu_create(ctx,
1333                         &dmcu_regs,
1334                         &dmcu_shift,
1335                         &dmcu_mask);
1336         if (pool->base.dmcu == NULL) {
1337                 dm_error("DC: failed to create dmcu!\n");
1338                 BREAK_TO_DEBUGGER();
1339                 goto res_create_fail;
1340         }
1341
1342         pool->base.abm = dce_abm_create(ctx,
1343                         &abm_regs,
1344                         &abm_shift,
1345                         &abm_mask);
1346         if (pool->base.abm == NULL) {
1347                 dm_error("DC: failed to create abm!\n");
1348                 BREAK_TO_DEBUGGER();
1349                 goto res_create_fail;
1350         }
1351
1352         {
1353                 struct irq_service_init_data init_data;
1354                 init_data.ctx = dc->ctx;
1355                 pool->base.irqs = dal_irq_service_dce110_create(&init_data);
1356                 if (!pool->base.irqs)
1357                         goto res_create_fail;
1358         }
1359
1360         for (i = 0; i < pool->base.pipe_count; i++) {
1361                 pool->base.timing_generators[i] = dce110_timing_generator_create(
1362                                 ctx, i, &dce110_tg_offsets[i]);
1363                 if (pool->base.timing_generators[i] == NULL) {
1364                         BREAK_TO_DEBUGGER();
1365                         dm_error("DC: failed to create tg!\n");
1366                         goto res_create_fail;
1367                 }
1368
1369                 pool->base.mis[i] = dce110_mem_input_create(ctx, i);
1370                 if (pool->base.mis[i] == NULL) {
1371                         BREAK_TO_DEBUGGER();
1372                         dm_error(
1373                                 "DC: failed to create memory input!\n");
1374                         goto res_create_fail;
1375                 }
1376
1377                 pool->base.ipps[i] = dce110_ipp_create(ctx, i);
1378                 if (pool->base.ipps[i] == NULL) {
1379                         BREAK_TO_DEBUGGER();
1380                         dm_error(
1381                                 "DC: failed to create input pixel processor!\n");
1382                         goto res_create_fail;
1383                 }
1384
1385                 pool->base.transforms[i] = dce110_transform_create(ctx, i);
1386                 if (pool->base.transforms[i] == NULL) {
1387                         BREAK_TO_DEBUGGER();
1388                         dm_error(
1389                                 "DC: failed to create transform!\n");
1390                         goto res_create_fail;
1391                 }
1392
1393                 pool->base.opps[i] = dce110_opp_create(ctx, i);
1394                 if (pool->base.opps[i] == NULL) {
1395                         BREAK_TO_DEBUGGER();
1396                         dm_error(
1397                                 "DC: failed to create output pixel processor!\n");
1398                         goto res_create_fail;
1399                 }
1400         }
1401
1402         for (i = 0; i < pool->base.res_cap->num_ddc; i++) {
1403                 pool->base.engines[i] = dce110_aux_engine_create(ctx, i);
1404                 if (pool->base.engines[i] == NULL) {
1405                         BREAK_TO_DEBUGGER();
1406                         dm_error(
1407                                 "DC:failed to create aux engine!!\n");
1408                         goto res_create_fail;
1409                 }
1410                 pool->base.hw_i2cs[i] = dce110_i2c_hw_create(ctx, i);
1411                 if (pool->base.hw_i2cs[i] == NULL) {
1412                         BREAK_TO_DEBUGGER();
1413                         dm_error(
1414                                 "DC:failed to create i2c engine!!\n");
1415                         goto res_create_fail;
1416                 }
1417                 pool->base.sw_i2cs[i] = NULL;
1418         }
1419
1420         if (dc->config.fbc_support)
1421                 dc->fbc_compressor = dce110_compressor_create(ctx);
1422
1423         if (!underlay_create(ctx, &pool->base))
1424                 goto res_create_fail;
1425
1426         if (!resource_construct(num_virtual_links, dc, &pool->base,
1427                         &res_create_funcs))
1428                 goto res_create_fail;
1429
1430         /* Create hardware sequencer */
1431         dce110_hw_sequencer_construct(dc);
1432
1433         dc->caps.max_planes =  pool->base.pipe_count;
1434
1435         for (i = 0; i < pool->base.underlay_pipe_index; ++i)
1436                 dc->caps.planes[i] = plane_cap;
1437
1438         dc->caps.planes[pool->base.underlay_pipe_index] = underlay_plane_cap;
1439
1440         bw_calcs_init(dc->bw_dceip, dc->bw_vbios, dc->ctx->asic_id);
1441
1442         bw_calcs_data_update_from_pplib(dc);
1443
1444         return true;
1445
1446 res_create_fail:
1447         destruct(pool);
1448         return false;
1449 }
1450
1451 struct resource_pool *dce110_create_resource_pool(
1452         uint8_t num_virtual_links,
1453         struct dc *dc,
1454         struct hw_asic_id asic_id)
1455 {
1456         struct dce110_resource_pool *pool =
1457                 kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
1458
1459         if (!pool)
1460                 return NULL;
1461
1462         if (construct(num_virtual_links, dc, pool, asic_id))
1463                 return &pool->base;
1464
1465         kfree(pool);
1466         BREAK_TO_DEBUGGER();
1467         return NULL;
1468 }