dce112_resource.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283
  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 "dm_services.h"
  26. #include "link_encoder.h"
  27. #include "stream_encoder.h"
  28. #include "resource.h"
  29. #include "include/irq_service_interface.h"
  30. #include "dce110/dce110_resource.h"
  31. #include "dce110/dce110_timing_generator.h"
  32. #include "irq/dce110/irq_service_dce110.h"
  33. #include "dce/dce_mem_input.h"
  34. #include "dce/dce_transform.h"
  35. #include "dce/dce_link_encoder.h"
  36. #include "dce/dce_stream_encoder.h"
  37. #include "dce/dce_audio.h"
  38. #include "dce/dce_opp.h"
  39. #include "dce/dce_ipp.h"
  40. #include "dce/dce_clocks.h"
  41. #include "dce/dce_clock_source.h"
  42. #include "dce/dce_hwseq.h"
  43. #include "dce112/dce112_hw_sequencer.h"
  44. #include "dce/dce_abm.h"
  45. #include "dce/dce_dmcu.h"
  46. #include "reg_helper.h"
  47. #include "dce/dce_11_2_d.h"
  48. #include "dce/dce_11_2_sh_mask.h"
  49. #include "dce100/dce100_resource.h"
  50. #ifndef mmDP_DPHY_INTERNAL_CTRL
  51. #define mmDP_DPHY_INTERNAL_CTRL 0x4aa7
  52. #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x4aa7
  53. #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x4ba7
  54. #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x4ca7
  55. #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x4da7
  56. #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x4ea7
  57. #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x4fa7
  58. #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x54a7
  59. #define mmDP7_DP_DPHY_INTERNAL_CTRL 0x56a7
  60. #define mmDP8_DP_DPHY_INTERNAL_CTRL 0x57a7
  61. #endif
  62. #ifndef mmBIOS_SCRATCH_2
  63. #define mmBIOS_SCRATCH_2 0x05CB
  64. #define mmBIOS_SCRATCH_6 0x05CF
  65. #endif
  66. #ifndef mmDP_DPHY_BS_SR_SWAP_CNTL
  67. #define mmDP_DPHY_BS_SR_SWAP_CNTL 0x4ADC
  68. #define mmDP0_DP_DPHY_BS_SR_SWAP_CNTL 0x4ADC
  69. #define mmDP1_DP_DPHY_BS_SR_SWAP_CNTL 0x4BDC
  70. #define mmDP2_DP_DPHY_BS_SR_SWAP_CNTL 0x4CDC
  71. #define mmDP3_DP_DPHY_BS_SR_SWAP_CNTL 0x4DDC
  72. #define mmDP4_DP_DPHY_BS_SR_SWAP_CNTL 0x4EDC
  73. #define mmDP5_DP_DPHY_BS_SR_SWAP_CNTL 0x4FDC
  74. #define mmDP6_DP_DPHY_BS_SR_SWAP_CNTL 0x54DC
  75. #endif
  76. #ifndef mmDP_DPHY_FAST_TRAINING
  77. #define mmDP_DPHY_FAST_TRAINING 0x4ABC
  78. #define mmDP0_DP_DPHY_FAST_TRAINING 0x4ABC
  79. #define mmDP1_DP_DPHY_FAST_TRAINING 0x4BBC
  80. #define mmDP2_DP_DPHY_FAST_TRAINING 0x4CBC
  81. #define mmDP3_DP_DPHY_FAST_TRAINING 0x4DBC
  82. #define mmDP4_DP_DPHY_FAST_TRAINING 0x4EBC
  83. #define mmDP5_DP_DPHY_FAST_TRAINING 0x4FBC
  84. #define mmDP6_DP_DPHY_FAST_TRAINING 0x54BC
  85. #endif
  86. enum dce112_clk_src_array_id {
  87. DCE112_CLK_SRC_PLL0,
  88. DCE112_CLK_SRC_PLL1,
  89. DCE112_CLK_SRC_PLL2,
  90. DCE112_CLK_SRC_PLL3,
  91. DCE112_CLK_SRC_PLL4,
  92. DCE112_CLK_SRC_PLL5,
  93. DCE112_CLK_SRC_TOTAL
  94. };
  95. static const struct dce110_timing_generator_offsets dce112_tg_offsets[] = {
  96. {
  97. .crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL),
  98. .dcp = (mmDCP0_GRPH_CONTROL - mmGRPH_CONTROL),
  99. },
  100. {
  101. .crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL),
  102. .dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL),
  103. },
  104. {
  105. .crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL),
  106. .dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL),
  107. },
  108. {
  109. .crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL),
  110. .dcp = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL),
  111. },
  112. {
  113. .crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL),
  114. .dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL),
  115. },
  116. {
  117. .crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL),
  118. .dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL),
  119. }
  120. };
  121. /* set register offset */
  122. #define SR(reg_name)\
  123. .reg_name = mm ## reg_name
  124. /* set register offset with instance */
  125. #define SRI(reg_name, block, id)\
  126. .reg_name = mm ## block ## id ## _ ## reg_name
  127. static const struct dce_disp_clk_registers disp_clk_regs = {
  128. CLK_COMMON_REG_LIST_DCE_BASE()
  129. };
  130. static const struct dce_disp_clk_shift disp_clk_shift = {
  131. CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
  132. };
  133. static const struct dce_disp_clk_mask disp_clk_mask = {
  134. CLK_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
  135. };
  136. static const struct dce_dmcu_registers dmcu_regs = {
  137. DMCU_DCE110_COMMON_REG_LIST()
  138. };
  139. static const struct dce_dmcu_shift dmcu_shift = {
  140. DMCU_MASK_SH_LIST_DCE110(__SHIFT)
  141. };
  142. static const struct dce_dmcu_mask dmcu_mask = {
  143. DMCU_MASK_SH_LIST_DCE110(_MASK)
  144. };
  145. static const struct dce_abm_registers abm_regs = {
  146. ABM_DCE110_COMMON_REG_LIST()
  147. };
  148. static const struct dce_abm_shift abm_shift = {
  149. ABM_MASK_SH_LIST_DCE110(__SHIFT)
  150. };
  151. static const struct dce_abm_mask abm_mask = {
  152. ABM_MASK_SH_LIST_DCE110(_MASK)
  153. };
  154. #define ipp_regs(id)\
  155. [id] = {\
  156. IPP_DCE110_REG_LIST_DCE_BASE(id)\
  157. }
  158. static const struct dce_ipp_registers ipp_regs[] = {
  159. ipp_regs(0),
  160. ipp_regs(1),
  161. ipp_regs(2),
  162. ipp_regs(3),
  163. ipp_regs(4),
  164. ipp_regs(5)
  165. };
  166. static const struct dce_ipp_shift ipp_shift = {
  167. IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(__SHIFT)
  168. };
  169. static const struct dce_ipp_mask ipp_mask = {
  170. IPP_DCE100_MASK_SH_LIST_DCE_COMMON_BASE(_MASK)
  171. };
  172. #define transform_regs(id)\
  173. [id] = {\
  174. XFM_COMMON_REG_LIST_DCE110(id)\
  175. }
  176. static const struct dce_transform_registers xfm_regs[] = {
  177. transform_regs(0),
  178. transform_regs(1),
  179. transform_regs(2),
  180. transform_regs(3),
  181. transform_regs(4),
  182. transform_regs(5)
  183. };
  184. static const struct dce_transform_shift xfm_shift = {
  185. XFM_COMMON_MASK_SH_LIST_DCE110(__SHIFT)
  186. };
  187. static const struct dce_transform_mask xfm_mask = {
  188. XFM_COMMON_MASK_SH_LIST_DCE110(_MASK)
  189. };
  190. #define aux_regs(id)\
  191. [id] = {\
  192. AUX_REG_LIST(id)\
  193. }
  194. static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
  195. aux_regs(0),
  196. aux_regs(1),
  197. aux_regs(2),
  198. aux_regs(3),
  199. aux_regs(4),
  200. aux_regs(5)
  201. };
  202. #define hpd_regs(id)\
  203. [id] = {\
  204. HPD_REG_LIST(id)\
  205. }
  206. static const struct dce110_link_enc_hpd_registers link_enc_hpd_regs[] = {
  207. hpd_regs(0),
  208. hpd_regs(1),
  209. hpd_regs(2),
  210. hpd_regs(3),
  211. hpd_regs(4),
  212. hpd_regs(5)
  213. };
  214. #define link_regs(id)\
  215. [id] = {\
  216. LE_DCE110_REG_LIST(id)\
  217. }
  218. static const struct dce110_link_enc_registers link_enc_regs[] = {
  219. link_regs(0),
  220. link_regs(1),
  221. link_regs(2),
  222. link_regs(3),
  223. link_regs(4),
  224. link_regs(5),
  225. link_regs(6),
  226. };
  227. #define stream_enc_regs(id)\
  228. [id] = {\
  229. SE_COMMON_REG_LIST(id),\
  230. .TMDS_CNTL = 0,\
  231. }
  232. static const struct dce110_stream_enc_registers stream_enc_regs[] = {
  233. stream_enc_regs(0),
  234. stream_enc_regs(1),
  235. stream_enc_regs(2),
  236. stream_enc_regs(3),
  237. stream_enc_regs(4),
  238. stream_enc_regs(5)
  239. };
  240. static const struct dce_stream_encoder_shift se_shift = {
  241. SE_COMMON_MASK_SH_LIST_DCE112(__SHIFT)
  242. };
  243. static const struct dce_stream_encoder_mask se_mask = {
  244. SE_COMMON_MASK_SH_LIST_DCE112(_MASK)
  245. };
  246. #define opp_regs(id)\
  247. [id] = {\
  248. OPP_DCE_112_REG_LIST(id),\
  249. }
  250. static const struct dce_opp_registers opp_regs[] = {
  251. opp_regs(0),
  252. opp_regs(1),
  253. opp_regs(2),
  254. opp_regs(3),
  255. opp_regs(4),
  256. opp_regs(5)
  257. };
  258. static const struct dce_opp_shift opp_shift = {
  259. OPP_COMMON_MASK_SH_LIST_DCE_112(__SHIFT)
  260. };
  261. static const struct dce_opp_mask opp_mask = {
  262. OPP_COMMON_MASK_SH_LIST_DCE_112(_MASK)
  263. };
  264. #define audio_regs(id)\
  265. [id] = {\
  266. AUD_COMMON_REG_LIST(id)\
  267. }
  268. static const struct dce_audio_registers audio_regs[] = {
  269. audio_regs(0),
  270. audio_regs(1),
  271. audio_regs(2),
  272. audio_regs(3),
  273. audio_regs(4),
  274. audio_regs(5)
  275. };
  276. static const struct dce_audio_shift audio_shift = {
  277. AUD_COMMON_MASK_SH_LIST(__SHIFT)
  278. };
  279. static const struct dce_aduio_mask audio_mask = {
  280. AUD_COMMON_MASK_SH_LIST(_MASK)
  281. };
  282. #define clk_src_regs(index, id)\
  283. [index] = {\
  284. CS_COMMON_REG_LIST_DCE_112(id),\
  285. }
  286. static const struct dce110_clk_src_regs clk_src_regs[] = {
  287. clk_src_regs(0, A),
  288. clk_src_regs(1, B),
  289. clk_src_regs(2, C),
  290. clk_src_regs(3, D),
  291. clk_src_regs(4, E),
  292. clk_src_regs(5, F)
  293. };
  294. static const struct dce110_clk_src_shift cs_shift = {
  295. CS_COMMON_MASK_SH_LIST_DCE_112(__SHIFT)
  296. };
  297. static const struct dce110_clk_src_mask cs_mask = {
  298. CS_COMMON_MASK_SH_LIST_DCE_112(_MASK)
  299. };
  300. static const struct bios_registers bios_regs = {
  301. .BIOS_SCRATCH_6 = mmBIOS_SCRATCH_6
  302. };
  303. static const struct resource_caps polaris_10_resource_cap = {
  304. .num_timing_generator = 6,
  305. .num_audio = 6,
  306. .num_stream_encoder = 6,
  307. .num_pll = 8, /* why 8? 6 combo PHY PLL + 2 regular PLLs? */
  308. };
  309. static const struct resource_caps polaris_11_resource_cap = {
  310. .num_timing_generator = 5,
  311. .num_audio = 5,
  312. .num_stream_encoder = 5,
  313. .num_pll = 8, /* why 8? 6 combo PHY PLL + 2 regular PLLs? */
  314. };
  315. #define CTX ctx
  316. #define REG(reg) mm ## reg
  317. #ifndef mmCC_DC_HDMI_STRAPS
  318. #define mmCC_DC_HDMI_STRAPS 0x4819
  319. #define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40
  320. #define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6
  321. #define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700
  322. #define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
  323. #endif
  324. static void read_dce_straps(
  325. struct dc_context *ctx,
  326. struct resource_straps *straps)
  327. {
  328. REG_GET_2(CC_DC_HDMI_STRAPS,
  329. HDMI_DISABLE, &straps->hdmi_disable,
  330. AUDIO_STREAM_NUMBER, &straps->audio_stream_number);
  331. REG_GET(DC_PINSTRAPS, DC_PINSTRAPS_AUDIO, &straps->dc_pinstraps_audio);
  332. }
  333. static struct audio *create_audio(
  334. struct dc_context *ctx, unsigned int inst)
  335. {
  336. return dce_audio_create(ctx, inst,
  337. &audio_regs[inst], &audio_shift, &audio_mask);
  338. }
  339. static struct timing_generator *dce112_timing_generator_create(
  340. struct dc_context *ctx,
  341. uint32_t instance,
  342. const struct dce110_timing_generator_offsets *offsets)
  343. {
  344. struct dce110_timing_generator *tg110 =
  345. kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL);
  346. if (!tg110)
  347. return NULL;
  348. dce110_timing_generator_construct(tg110, ctx, instance, offsets);
  349. return &tg110->base;
  350. }
  351. static struct stream_encoder *dce112_stream_encoder_create(
  352. enum engine_id eng_id,
  353. struct dc_context *ctx)
  354. {
  355. struct dce110_stream_encoder *enc110 =
  356. kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL);
  357. if (!enc110)
  358. return NULL;
  359. dce110_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
  360. &stream_enc_regs[eng_id],
  361. &se_shift, &se_mask);
  362. return &enc110->base;
  363. }
  364. #define SRII(reg_name, block, id)\
  365. .reg_name[id] = mm ## block ## id ## _ ## reg_name
  366. static const struct dce_hwseq_registers hwseq_reg = {
  367. HWSEQ_DCE112_REG_LIST()
  368. };
  369. static const struct dce_hwseq_shift hwseq_shift = {
  370. HWSEQ_DCE112_MASK_SH_LIST(__SHIFT)
  371. };
  372. static const struct dce_hwseq_mask hwseq_mask = {
  373. HWSEQ_DCE112_MASK_SH_LIST(_MASK)
  374. };
  375. static struct dce_hwseq *dce112_hwseq_create(
  376. struct dc_context *ctx)
  377. {
  378. struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
  379. if (hws) {
  380. hws->ctx = ctx;
  381. hws->regs = &hwseq_reg;
  382. hws->shifts = &hwseq_shift;
  383. hws->masks = &hwseq_mask;
  384. }
  385. return hws;
  386. }
  387. static const struct resource_create_funcs res_create_funcs = {
  388. .read_dce_straps = read_dce_straps,
  389. .create_audio = create_audio,
  390. .create_stream_encoder = dce112_stream_encoder_create,
  391. .create_hwseq = dce112_hwseq_create,
  392. };
  393. #define mi_inst_regs(id) { MI_DCE11_2_REG_LIST(id) }
  394. static const struct dce_mem_input_registers mi_regs[] = {
  395. mi_inst_regs(0),
  396. mi_inst_regs(1),
  397. mi_inst_regs(2),
  398. mi_inst_regs(3),
  399. mi_inst_regs(4),
  400. mi_inst_regs(5),
  401. };
  402. static const struct dce_mem_input_shift mi_shifts = {
  403. MI_DCE11_2_MASK_SH_LIST(__SHIFT)
  404. };
  405. static const struct dce_mem_input_mask mi_masks = {
  406. MI_DCE11_2_MASK_SH_LIST(_MASK)
  407. };
  408. static struct mem_input *dce112_mem_input_create(
  409. struct dc_context *ctx,
  410. uint32_t inst)
  411. {
  412. struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input),
  413. GFP_KERNEL);
  414. if (!dce_mi) {
  415. BREAK_TO_DEBUGGER();
  416. return NULL;
  417. }
  418. dce112_mem_input_construct(dce_mi, ctx, inst, &mi_regs[inst], &mi_shifts, &mi_masks);
  419. return &dce_mi->base;
  420. }
  421. static void dce112_transform_destroy(struct transform **xfm)
  422. {
  423. kfree(TO_DCE_TRANSFORM(*xfm));
  424. *xfm = NULL;
  425. }
  426. static struct transform *dce112_transform_create(
  427. struct dc_context *ctx,
  428. uint32_t inst)
  429. {
  430. struct dce_transform *transform =
  431. kzalloc(sizeof(struct dce_transform), GFP_KERNEL);
  432. if (!transform)
  433. return NULL;
  434. dce_transform_construct(transform, ctx, inst,
  435. &xfm_regs[inst], &xfm_shift, &xfm_mask);
  436. transform->lb_memory_size = 0x1404; /*5124*/
  437. return &transform->base;
  438. }
  439. static const struct encoder_feature_support link_enc_feature = {
  440. .max_hdmi_deep_color = COLOR_DEPTH_121212,
  441. .max_hdmi_pixel_clock = 600000,
  442. .ycbcr420_supported = true,
  443. .flags.bits.IS_HBR2_CAPABLE = true,
  444. .flags.bits.IS_HBR3_CAPABLE = true,
  445. .flags.bits.IS_TPS3_CAPABLE = true,
  446. .flags.bits.IS_TPS4_CAPABLE = true,
  447. .flags.bits.IS_YCBCR_CAPABLE = true
  448. };
  449. struct link_encoder *dce112_link_encoder_create(
  450. const struct encoder_init_data *enc_init_data)
  451. {
  452. struct dce110_link_encoder *enc110 =
  453. kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL);
  454. if (!enc110)
  455. return NULL;
  456. dce110_link_encoder_construct(enc110,
  457. enc_init_data,
  458. &link_enc_feature,
  459. &link_enc_regs[enc_init_data->transmitter],
  460. &link_enc_aux_regs[enc_init_data->channel - 1],
  461. &link_enc_hpd_regs[enc_init_data->hpd_source]);
  462. return &enc110->base;
  463. }
  464. static struct input_pixel_processor *dce112_ipp_create(
  465. struct dc_context *ctx, uint32_t inst)
  466. {
  467. struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL);
  468. if (!ipp) {
  469. BREAK_TO_DEBUGGER();
  470. return NULL;
  471. }
  472. dce_ipp_construct(ipp, ctx, inst,
  473. &ipp_regs[inst], &ipp_shift, &ipp_mask);
  474. return &ipp->base;
  475. }
  476. struct output_pixel_processor *dce112_opp_create(
  477. struct dc_context *ctx,
  478. uint32_t inst)
  479. {
  480. struct dce110_opp *opp =
  481. kzalloc(sizeof(struct dce110_opp), GFP_KERNEL);
  482. if (!opp)
  483. return NULL;
  484. dce110_opp_construct(opp,
  485. ctx, inst, &opp_regs[inst], &opp_shift, &opp_mask);
  486. return &opp->base;
  487. }
  488. struct clock_source *dce112_clock_source_create(
  489. struct dc_context *ctx,
  490. struct dc_bios *bios,
  491. enum clock_source_id id,
  492. const struct dce110_clk_src_regs *regs,
  493. bool dp_clk_src)
  494. {
  495. struct dce110_clk_src *clk_src =
  496. kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
  497. if (!clk_src)
  498. return NULL;
  499. if (dce110_clk_src_construct(clk_src, ctx, bios, id,
  500. regs, &cs_shift, &cs_mask)) {
  501. clk_src->base.dp_clk_src = dp_clk_src;
  502. return &clk_src->base;
  503. }
  504. BREAK_TO_DEBUGGER();
  505. return NULL;
  506. }
  507. void dce112_clock_source_destroy(struct clock_source **clk_src)
  508. {
  509. kfree(TO_DCE110_CLK_SRC(*clk_src));
  510. *clk_src = NULL;
  511. }
  512. static void destruct(struct dce110_resource_pool *pool)
  513. {
  514. unsigned int i;
  515. for (i = 0; i < pool->base.pipe_count; i++) {
  516. if (pool->base.opps[i] != NULL)
  517. dce110_opp_destroy(&pool->base.opps[i]);
  518. if (pool->base.transforms[i] != NULL)
  519. dce112_transform_destroy(&pool->base.transforms[i]);
  520. if (pool->base.ipps[i] != NULL)
  521. dce_ipp_destroy(&pool->base.ipps[i]);
  522. if (pool->base.mis[i] != NULL) {
  523. kfree(TO_DCE_MEM_INPUT(pool->base.mis[i]));
  524. pool->base.mis[i] = NULL;
  525. }
  526. if (pool->base.timing_generators[i] != NULL) {
  527. kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i]));
  528. pool->base.timing_generators[i] = NULL;
  529. }
  530. }
  531. for (i = 0; i < pool->base.stream_enc_count; i++) {
  532. if (pool->base.stream_enc[i] != NULL)
  533. kfree(DCE110STRENC_FROM_STRENC(pool->base.stream_enc[i]));
  534. }
  535. for (i = 0; i < pool->base.clk_src_count; i++) {
  536. if (pool->base.clock_sources[i] != NULL) {
  537. dce112_clock_source_destroy(&pool->base.clock_sources[i]);
  538. }
  539. }
  540. if (pool->base.dp_clock_source != NULL)
  541. dce112_clock_source_destroy(&pool->base.dp_clock_source);
  542. for (i = 0; i < pool->base.audio_count; i++) {
  543. if (pool->base.audios[i] != NULL) {
  544. dce_aud_destroy(&pool->base.audios[i]);
  545. }
  546. }
  547. if (pool->base.abm != NULL)
  548. dce_abm_destroy(&pool->base.abm);
  549. if (pool->base.dmcu != NULL)
  550. dce_dmcu_destroy(&pool->base.dmcu);
  551. if (pool->base.display_clock != NULL)
  552. dce_disp_clk_destroy(&pool->base.display_clock);
  553. if (pool->base.irqs != NULL) {
  554. dal_irq_service_destroy(&pool->base.irqs);
  555. }
  556. }
  557. static struct clock_source *find_matching_pll(
  558. struct resource_context *res_ctx,
  559. const struct resource_pool *pool,
  560. const struct dc_stream_state *const stream)
  561. {
  562. switch (stream->sink->link->link_enc->transmitter) {
  563. case TRANSMITTER_UNIPHY_A:
  564. return pool->clock_sources[DCE112_CLK_SRC_PLL0];
  565. case TRANSMITTER_UNIPHY_B:
  566. return pool->clock_sources[DCE112_CLK_SRC_PLL1];
  567. case TRANSMITTER_UNIPHY_C:
  568. return pool->clock_sources[DCE112_CLK_SRC_PLL2];
  569. case TRANSMITTER_UNIPHY_D:
  570. return pool->clock_sources[DCE112_CLK_SRC_PLL3];
  571. case TRANSMITTER_UNIPHY_E:
  572. return pool->clock_sources[DCE112_CLK_SRC_PLL4];
  573. case TRANSMITTER_UNIPHY_F:
  574. return pool->clock_sources[DCE112_CLK_SRC_PLL5];
  575. default:
  576. return NULL;
  577. };
  578. return 0;
  579. }
  580. static enum dc_status build_mapped_resource(
  581. const struct dc *dc,
  582. struct dc_state *context,
  583. struct dc_stream_state *stream)
  584. {
  585. struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(&context->res_ctx, stream);
  586. if (!pipe_ctx)
  587. return DC_ERROR_UNEXPECTED;
  588. dce110_resource_build_pipe_hw_param(pipe_ctx);
  589. resource_build_info_frame(pipe_ctx);
  590. return DC_OK;
  591. }
  592. bool dce112_validate_bandwidth(
  593. struct dc *dc,
  594. struct dc_state *context)
  595. {
  596. bool result = false;
  597. dm_logger_write(
  598. dc->ctx->logger, LOG_BANDWIDTH_CALCS,
  599. "%s: start",
  600. __func__);
  601. if (bw_calcs(
  602. dc->ctx,
  603. dc->bw_dceip,
  604. dc->bw_vbios,
  605. context->res_ctx.pipe_ctx,
  606. dc->res_pool->pipe_count,
  607. &context->bw.dce))
  608. result = true;
  609. if (!result)
  610. dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_VALIDATION,
  611. "%s: Bandwidth validation failed!",
  612. __func__);
  613. if (memcmp(&dc->current_state->bw.dce,
  614. &context->bw.dce, sizeof(context->bw.dce))) {
  615. struct log_entry log_entry;
  616. dm_logger_open(
  617. dc->ctx->logger,
  618. &log_entry,
  619. LOG_BANDWIDTH_CALCS);
  620. dm_logger_append(&log_entry, "%s: finish,\n"
  621. "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
  622. "stutMark_b: %d stutMark_a: %d\n",
  623. __func__,
  624. context->bw.dce.nbp_state_change_wm_ns[0].b_mark,
  625. context->bw.dce.nbp_state_change_wm_ns[0].a_mark,
  626. context->bw.dce.urgent_wm_ns[0].b_mark,
  627. context->bw.dce.urgent_wm_ns[0].a_mark,
  628. context->bw.dce.stutter_exit_wm_ns[0].b_mark,
  629. context->bw.dce.stutter_exit_wm_ns[0].a_mark);
  630. dm_logger_append(&log_entry,
  631. "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
  632. "stutMark_b: %d stutMark_a: %d\n",
  633. context->bw.dce.nbp_state_change_wm_ns[1].b_mark,
  634. context->bw.dce.nbp_state_change_wm_ns[1].a_mark,
  635. context->bw.dce.urgent_wm_ns[1].b_mark,
  636. context->bw.dce.urgent_wm_ns[1].a_mark,
  637. context->bw.dce.stutter_exit_wm_ns[1].b_mark,
  638. context->bw.dce.stutter_exit_wm_ns[1].a_mark);
  639. dm_logger_append(&log_entry,
  640. "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
  641. "stutMark_b: %d stutMark_a: %d stutter_mode_enable: %d\n",
  642. context->bw.dce.nbp_state_change_wm_ns[2].b_mark,
  643. context->bw.dce.nbp_state_change_wm_ns[2].a_mark,
  644. context->bw.dce.urgent_wm_ns[2].b_mark,
  645. context->bw.dce.urgent_wm_ns[2].a_mark,
  646. context->bw.dce.stutter_exit_wm_ns[2].b_mark,
  647. context->bw.dce.stutter_exit_wm_ns[2].a_mark,
  648. context->bw.dce.stutter_mode_enable);
  649. dm_logger_append(&log_entry,
  650. "cstate: %d pstate: %d nbpstate: %d sync: %d dispclk: %d\n"
  651. "sclk: %d sclk_sleep: %d yclk: %d blackout_recovery_time_us: %d\n",
  652. context->bw.dce.cpuc_state_change_enable,
  653. context->bw.dce.cpup_state_change_enable,
  654. context->bw.dce.nbp_state_change_enable,
  655. context->bw.dce.all_displays_in_sync,
  656. context->bw.dce.dispclk_khz,
  657. context->bw.dce.sclk_khz,
  658. context->bw.dce.sclk_deep_sleep_khz,
  659. context->bw.dce.yclk_khz,
  660. context->bw.dce.blackout_recovery_time_us);
  661. dm_logger_close(&log_entry);
  662. }
  663. return result;
  664. }
  665. enum dc_status resource_map_phy_clock_resources(
  666. const struct dc *dc,
  667. struct dc_state *context,
  668. struct dc_stream_state *stream)
  669. {
  670. /* acquire new resources */
  671. struct pipe_ctx *pipe_ctx = resource_get_head_pipe_for_stream(
  672. &context->res_ctx, stream);
  673. if (!pipe_ctx)
  674. return DC_ERROR_UNEXPECTED;
  675. if (dc_is_dp_signal(pipe_ctx->stream->signal)
  676. || pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL)
  677. pipe_ctx->clock_source =
  678. dc->res_pool->dp_clock_source;
  679. else
  680. pipe_ctx->clock_source = find_matching_pll(
  681. &context->res_ctx, dc->res_pool,
  682. stream);
  683. if (pipe_ctx->clock_source == NULL)
  684. return DC_NO_CLOCK_SOURCE_RESOURCE;
  685. resource_reference_clock_source(
  686. &context->res_ctx,
  687. dc->res_pool,
  688. pipe_ctx->clock_source);
  689. return DC_OK;
  690. }
  691. static bool dce112_validate_surface_sets(
  692. struct dc_state *context)
  693. {
  694. int i;
  695. for (i = 0; i < context->stream_count; i++) {
  696. if (context->stream_status[i].plane_count == 0)
  697. continue;
  698. if (context->stream_status[i].plane_count > 1)
  699. return false;
  700. if (context->stream_status[i].plane_states[0]->format
  701. >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
  702. return false;
  703. }
  704. return true;
  705. }
  706. enum dc_status dce112_add_stream_to_ctx(
  707. struct dc *dc,
  708. struct dc_state *new_ctx,
  709. struct dc_stream_state *dc_stream)
  710. {
  711. enum dc_status result = DC_ERROR_UNEXPECTED;
  712. result = resource_map_pool_resources(dc, new_ctx, dc_stream);
  713. if (result == DC_OK)
  714. result = resource_map_phy_clock_resources(dc, new_ctx, dc_stream);
  715. if (result == DC_OK)
  716. result = build_mapped_resource(dc, new_ctx, dc_stream);
  717. return result;
  718. }
  719. enum dc_status dce112_validate_guaranteed(
  720. struct dc *dc,
  721. struct dc_stream_state *stream,
  722. struct dc_state *context)
  723. {
  724. enum dc_status result = DC_ERROR_UNEXPECTED;
  725. context->streams[0] = stream;
  726. dc_stream_retain(context->streams[0]);
  727. context->stream_count++;
  728. result = resource_map_pool_resources(dc, context, stream);
  729. if (result == DC_OK)
  730. result = resource_map_phy_clock_resources(dc, context, stream);
  731. if (result == DC_OK)
  732. result = build_mapped_resource(dc, context, stream);
  733. if (result == DC_OK) {
  734. validate_guaranteed_copy_streams(
  735. context, dc->caps.max_streams);
  736. result = resource_build_scaling_params_for_context(dc, context);
  737. }
  738. if (result == DC_OK)
  739. if (!dce112_validate_bandwidth(dc, context))
  740. result = DC_FAIL_BANDWIDTH_VALIDATE;
  741. return result;
  742. }
  743. enum dc_status dce112_validate_global(
  744. struct dc *dc,
  745. struct dc_state *context)
  746. {
  747. if (!dce112_validate_surface_sets(context))
  748. return DC_FAIL_SURFACE_VALIDATE;
  749. return DC_OK;
  750. }
  751. static void dce112_destroy_resource_pool(struct resource_pool **pool)
  752. {
  753. struct dce110_resource_pool *dce110_pool = TO_DCE110_RES_POOL(*pool);
  754. destruct(dce110_pool);
  755. kfree(dce110_pool);
  756. *pool = NULL;
  757. }
  758. static const struct resource_funcs dce112_res_pool_funcs = {
  759. .destroy = dce112_destroy_resource_pool,
  760. .link_enc_create = dce112_link_encoder_create,
  761. .validate_guaranteed = dce112_validate_guaranteed,
  762. .validate_bandwidth = dce112_validate_bandwidth,
  763. .validate_plane = dce100_validate_plane,
  764. .add_stream_to_ctx = dce112_add_stream_to_ctx,
  765. .validate_global = dce112_validate_global
  766. };
  767. static void bw_calcs_data_update_from_pplib(struct dc *dc)
  768. {
  769. struct dm_pp_clock_levels_with_latency eng_clks = {0};
  770. struct dm_pp_clock_levels_with_latency mem_clks = {0};
  771. struct dm_pp_wm_sets_with_clock_ranges clk_ranges = {0};
  772. struct dm_pp_clock_levels clks = {0};
  773. /*do system clock TODO PPLIB: after PPLIB implement,
  774. * then remove old way
  775. */
  776. if (!dm_pp_get_clock_levels_by_type_with_latency(
  777. dc->ctx,
  778. DM_PP_CLOCK_TYPE_ENGINE_CLK,
  779. &eng_clks)) {
  780. /* This is only for temporary */
  781. dm_pp_get_clock_levels_by_type(
  782. dc->ctx,
  783. DM_PP_CLOCK_TYPE_ENGINE_CLK,
  784. &clks);
  785. /* convert all the clock fro kHz to fix point mHz */
  786. dc->bw_vbios->high_sclk = bw_frc_to_fixed(
  787. clks.clocks_in_khz[clks.num_levels-1], 1000);
  788. dc->bw_vbios->mid1_sclk = bw_frc_to_fixed(
  789. clks.clocks_in_khz[clks.num_levels/8], 1000);
  790. dc->bw_vbios->mid2_sclk = bw_frc_to_fixed(
  791. clks.clocks_in_khz[clks.num_levels*2/8], 1000);
  792. dc->bw_vbios->mid3_sclk = bw_frc_to_fixed(
  793. clks.clocks_in_khz[clks.num_levels*3/8], 1000);
  794. dc->bw_vbios->mid4_sclk = bw_frc_to_fixed(
  795. clks.clocks_in_khz[clks.num_levels*4/8], 1000);
  796. dc->bw_vbios->mid5_sclk = bw_frc_to_fixed(
  797. clks.clocks_in_khz[clks.num_levels*5/8], 1000);
  798. dc->bw_vbios->mid6_sclk = bw_frc_to_fixed(
  799. clks.clocks_in_khz[clks.num_levels*6/8], 1000);
  800. dc->bw_vbios->low_sclk = bw_frc_to_fixed(
  801. clks.clocks_in_khz[0], 1000);
  802. /*do memory clock*/
  803. dm_pp_get_clock_levels_by_type(
  804. dc->ctx,
  805. DM_PP_CLOCK_TYPE_MEMORY_CLK,
  806. &clks);
  807. dc->bw_vbios->low_yclk = bw_frc_to_fixed(
  808. clks.clocks_in_khz[0] * MEMORY_TYPE_MULTIPLIER, 1000);
  809. dc->bw_vbios->mid_yclk = bw_frc_to_fixed(
  810. clks.clocks_in_khz[clks.num_levels>>1] * MEMORY_TYPE_MULTIPLIER,
  811. 1000);
  812. dc->bw_vbios->high_yclk = bw_frc_to_fixed(
  813. clks.clocks_in_khz[clks.num_levels-1] * MEMORY_TYPE_MULTIPLIER,
  814. 1000);
  815. return;
  816. }
  817. /* convert all the clock fro kHz to fix point mHz TODO: wloop data */
  818. dc->bw_vbios->high_sclk = bw_frc_to_fixed(
  819. eng_clks.data[eng_clks.num_levels-1].clocks_in_khz, 1000);
  820. dc->bw_vbios->mid1_sclk = bw_frc_to_fixed(
  821. eng_clks.data[eng_clks.num_levels/8].clocks_in_khz, 1000);
  822. dc->bw_vbios->mid2_sclk = bw_frc_to_fixed(
  823. eng_clks.data[eng_clks.num_levels*2/8].clocks_in_khz, 1000);
  824. dc->bw_vbios->mid3_sclk = bw_frc_to_fixed(
  825. eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz, 1000);
  826. dc->bw_vbios->mid4_sclk = bw_frc_to_fixed(
  827. eng_clks.data[eng_clks.num_levels*4/8].clocks_in_khz, 1000);
  828. dc->bw_vbios->mid5_sclk = bw_frc_to_fixed(
  829. eng_clks.data[eng_clks.num_levels*5/8].clocks_in_khz, 1000);
  830. dc->bw_vbios->mid6_sclk = bw_frc_to_fixed(
  831. eng_clks.data[eng_clks.num_levels*6/8].clocks_in_khz, 1000);
  832. dc->bw_vbios->low_sclk = bw_frc_to_fixed(
  833. eng_clks.data[0].clocks_in_khz, 1000);
  834. /*do memory clock*/
  835. dm_pp_get_clock_levels_by_type_with_latency(
  836. dc->ctx,
  837. DM_PP_CLOCK_TYPE_MEMORY_CLK,
  838. &mem_clks);
  839. /* we don't need to call PPLIB for validation clock since they
  840. * also give us the highest sclk and highest mclk (UMA clock).
  841. * ALSO always convert UMA clock (from PPLIB) to YCLK (HW formula):
  842. * YCLK = UMACLK*m_memoryTypeMultiplier
  843. */
  844. dc->bw_vbios->low_yclk = bw_frc_to_fixed(
  845. mem_clks.data[0].clocks_in_khz * MEMORY_TYPE_MULTIPLIER, 1000);
  846. dc->bw_vbios->mid_yclk = bw_frc_to_fixed(
  847. mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER,
  848. 1000);
  849. dc->bw_vbios->high_yclk = bw_frc_to_fixed(
  850. mem_clks.data[mem_clks.num_levels-1].clocks_in_khz * MEMORY_TYPE_MULTIPLIER,
  851. 1000);
  852. /* Now notify PPLib/SMU about which Watermarks sets they should select
  853. * depending on DPM state they are in. And update BW MGR GFX Engine and
  854. * Memory clock member variables for Watermarks calculations for each
  855. * Watermark Set
  856. */
  857. clk_ranges.num_wm_sets = 4;
  858. clk_ranges.wm_clk_ranges[0].wm_set_id = WM_SET_A;
  859. clk_ranges.wm_clk_ranges[0].wm_min_eng_clk_in_khz =
  860. eng_clks.data[0].clocks_in_khz;
  861. clk_ranges.wm_clk_ranges[0].wm_max_eng_clk_in_khz =
  862. eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1;
  863. clk_ranges.wm_clk_ranges[0].wm_min_memg_clk_in_khz =
  864. mem_clks.data[0].clocks_in_khz;
  865. clk_ranges.wm_clk_ranges[0].wm_max_mem_clk_in_khz =
  866. mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1;
  867. clk_ranges.wm_clk_ranges[1].wm_set_id = WM_SET_B;
  868. clk_ranges.wm_clk_ranges[1].wm_min_eng_clk_in_khz =
  869. eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz;
  870. /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
  871. clk_ranges.wm_clk_ranges[1].wm_max_eng_clk_in_khz = 5000000;
  872. clk_ranges.wm_clk_ranges[1].wm_min_memg_clk_in_khz =
  873. mem_clks.data[0].clocks_in_khz;
  874. clk_ranges.wm_clk_ranges[1].wm_max_mem_clk_in_khz =
  875. mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz - 1;
  876. clk_ranges.wm_clk_ranges[2].wm_set_id = WM_SET_C;
  877. clk_ranges.wm_clk_ranges[2].wm_min_eng_clk_in_khz =
  878. eng_clks.data[0].clocks_in_khz;
  879. clk_ranges.wm_clk_ranges[2].wm_max_eng_clk_in_khz =
  880. eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz - 1;
  881. clk_ranges.wm_clk_ranges[2].wm_min_memg_clk_in_khz =
  882. mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz;
  883. /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
  884. clk_ranges.wm_clk_ranges[2].wm_max_mem_clk_in_khz = 5000000;
  885. clk_ranges.wm_clk_ranges[3].wm_set_id = WM_SET_D;
  886. clk_ranges.wm_clk_ranges[3].wm_min_eng_clk_in_khz =
  887. eng_clks.data[eng_clks.num_levels*3/8].clocks_in_khz;
  888. /* 5 GHz instead of data[7].clockInKHz to cover Overdrive */
  889. clk_ranges.wm_clk_ranges[3].wm_max_eng_clk_in_khz = 5000000;
  890. clk_ranges.wm_clk_ranges[3].wm_min_memg_clk_in_khz =
  891. mem_clks.data[mem_clks.num_levels>>1].clocks_in_khz;
  892. /* 5 GHz instead of data[2].clockInKHz to cover Overdrive */
  893. clk_ranges.wm_clk_ranges[3].wm_max_mem_clk_in_khz = 5000000;
  894. /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */
  895. dm_pp_notify_wm_clock_changes(dc->ctx, &clk_ranges);
  896. }
  897. const struct resource_caps *dce112_resource_cap(
  898. struct hw_asic_id *asic_id)
  899. {
  900. if (ASIC_REV_IS_POLARIS11_M(asic_id->hw_internal_rev) ||
  901. ASIC_REV_IS_POLARIS12_V(asic_id->hw_internal_rev))
  902. return &polaris_11_resource_cap;
  903. else
  904. return &polaris_10_resource_cap;
  905. }
  906. static bool construct(
  907. uint8_t num_virtual_links,
  908. struct dc *dc,
  909. struct dce110_resource_pool *pool)
  910. {
  911. unsigned int i;
  912. struct dc_context *ctx = dc->ctx;
  913. struct dm_pp_static_clock_info static_clk_info = {0};
  914. ctx->dc_bios->regs = &bios_regs;
  915. pool->base.res_cap = dce112_resource_cap(&ctx->asic_id);
  916. pool->base.funcs = &dce112_res_pool_funcs;
  917. /*************************************************
  918. * Resource + asic cap harcoding *
  919. *************************************************/
  920. pool->base.underlay_pipe_index = NO_UNDERLAY_PIPE;
  921. pool->base.pipe_count = pool->base.res_cap->num_timing_generator;
  922. dc->caps.max_downscale_ratio = 200;
  923. dc->caps.i2c_speed_in_khz = 100;
  924. dc->caps.max_cursor_size = 128;
  925. /*************************************************
  926. * Create resources *
  927. *************************************************/
  928. pool->base.clock_sources[DCE112_CLK_SRC_PLL0] =
  929. dce112_clock_source_create(
  930. ctx, ctx->dc_bios,
  931. CLOCK_SOURCE_COMBO_PHY_PLL0,
  932. &clk_src_regs[0], false);
  933. pool->base.clock_sources[DCE112_CLK_SRC_PLL1] =
  934. dce112_clock_source_create(
  935. ctx, ctx->dc_bios,
  936. CLOCK_SOURCE_COMBO_PHY_PLL1,
  937. &clk_src_regs[1], false);
  938. pool->base.clock_sources[DCE112_CLK_SRC_PLL2] =
  939. dce112_clock_source_create(
  940. ctx, ctx->dc_bios,
  941. CLOCK_SOURCE_COMBO_PHY_PLL2,
  942. &clk_src_regs[2], false);
  943. pool->base.clock_sources[DCE112_CLK_SRC_PLL3] =
  944. dce112_clock_source_create(
  945. ctx, ctx->dc_bios,
  946. CLOCK_SOURCE_COMBO_PHY_PLL3,
  947. &clk_src_regs[3], false);
  948. pool->base.clock_sources[DCE112_CLK_SRC_PLL4] =
  949. dce112_clock_source_create(
  950. ctx, ctx->dc_bios,
  951. CLOCK_SOURCE_COMBO_PHY_PLL4,
  952. &clk_src_regs[4], false);
  953. pool->base.clock_sources[DCE112_CLK_SRC_PLL5] =
  954. dce112_clock_source_create(
  955. ctx, ctx->dc_bios,
  956. CLOCK_SOURCE_COMBO_PHY_PLL5,
  957. &clk_src_regs[5], false);
  958. pool->base.clk_src_count = DCE112_CLK_SRC_TOTAL;
  959. pool->base.dp_clock_source = dce112_clock_source_create(
  960. ctx, ctx->dc_bios,
  961. CLOCK_SOURCE_ID_DP_DTO, &clk_src_regs[0], true);
  962. for (i = 0; i < pool->base.clk_src_count; i++) {
  963. if (pool->base.clock_sources[i] == NULL) {
  964. dm_error("DC: failed to create clock sources!\n");
  965. BREAK_TO_DEBUGGER();
  966. goto res_create_fail;
  967. }
  968. }
  969. pool->base.display_clock = dce112_disp_clk_create(ctx,
  970. &disp_clk_regs,
  971. &disp_clk_shift,
  972. &disp_clk_mask);
  973. if (pool->base.display_clock == NULL) {
  974. dm_error("DC: failed to create display clock!\n");
  975. BREAK_TO_DEBUGGER();
  976. goto res_create_fail;
  977. }
  978. pool->base.dmcu = dce_dmcu_create(ctx,
  979. &dmcu_regs,
  980. &dmcu_shift,
  981. &dmcu_mask);
  982. if (pool->base.dmcu == NULL) {
  983. dm_error("DC: failed to create dmcu!\n");
  984. BREAK_TO_DEBUGGER();
  985. goto res_create_fail;
  986. }
  987. pool->base.abm = dce_abm_create(ctx,
  988. &abm_regs,
  989. &abm_shift,
  990. &abm_mask);
  991. if (pool->base.abm == NULL) {
  992. dm_error("DC: failed to create abm!\n");
  993. BREAK_TO_DEBUGGER();
  994. goto res_create_fail;
  995. }
  996. /* get static clock information for PPLIB or firmware, save
  997. * max_clock_state
  998. */
  999. if (dm_pp_get_static_clocks(ctx, &static_clk_info))
  1000. pool->base.display_clock->max_clks_state =
  1001. static_clk_info.max_clocks_state;
  1002. {
  1003. struct irq_service_init_data init_data;
  1004. init_data.ctx = dc->ctx;
  1005. pool->base.irqs = dal_irq_service_dce110_create(&init_data);
  1006. if (!pool->base.irqs)
  1007. goto res_create_fail;
  1008. }
  1009. for (i = 0; i < pool->base.pipe_count; i++) {
  1010. pool->base.timing_generators[i] =
  1011. dce112_timing_generator_create(
  1012. ctx,
  1013. i,
  1014. &dce112_tg_offsets[i]);
  1015. if (pool->base.timing_generators[i] == NULL) {
  1016. BREAK_TO_DEBUGGER();
  1017. dm_error("DC: failed to create tg!\n");
  1018. goto res_create_fail;
  1019. }
  1020. pool->base.mis[i] = dce112_mem_input_create(ctx, i);
  1021. if (pool->base.mis[i] == NULL) {
  1022. BREAK_TO_DEBUGGER();
  1023. dm_error(
  1024. "DC: failed to create memory input!\n");
  1025. goto res_create_fail;
  1026. }
  1027. pool->base.ipps[i] = dce112_ipp_create(ctx, i);
  1028. if (pool->base.ipps[i] == NULL) {
  1029. BREAK_TO_DEBUGGER();
  1030. dm_error(
  1031. "DC:failed to create input pixel processor!\n");
  1032. goto res_create_fail;
  1033. }
  1034. pool->base.transforms[i] = dce112_transform_create(ctx, i);
  1035. if (pool->base.transforms[i] == NULL) {
  1036. BREAK_TO_DEBUGGER();
  1037. dm_error(
  1038. "DC: failed to create transform!\n");
  1039. goto res_create_fail;
  1040. }
  1041. pool->base.opps[i] = dce112_opp_create(
  1042. ctx,
  1043. i);
  1044. if (pool->base.opps[i] == NULL) {
  1045. BREAK_TO_DEBUGGER();
  1046. dm_error(
  1047. "DC:failed to create output pixel processor!\n");
  1048. goto res_create_fail;
  1049. }
  1050. }
  1051. if (!resource_construct(num_virtual_links, dc, &pool->base,
  1052. &res_create_funcs))
  1053. goto res_create_fail;
  1054. dc->caps.max_planes = pool->base.pipe_count;
  1055. /* Create hardware sequencer */
  1056. dce112_hw_sequencer_construct(dc);
  1057. bw_calcs_init(dc->bw_dceip, dc->bw_vbios, dc->ctx->asic_id);
  1058. bw_calcs_data_update_from_pplib(dc);
  1059. return true;
  1060. res_create_fail:
  1061. destruct(pool);
  1062. return false;
  1063. }
  1064. struct resource_pool *dce112_create_resource_pool(
  1065. uint8_t num_virtual_links,
  1066. struct dc *dc)
  1067. {
  1068. struct dce110_resource_pool *pool =
  1069. kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL);
  1070. if (!pool)
  1071. return NULL;
  1072. if (construct(num_virtual_links, dc, pool))
  1073. return &pool->base;
  1074. BREAK_TO_DEBUGGER();
  1075. return NULL;
  1076. }