dce80_resource.c 32 KB

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