bios_parser2.c 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934
  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 "ObjectID.h"
  27. #include "atomfirmware.h"
  28. #include "dc_bios_types.h"
  29. #include "include/grph_object_ctrl_defs.h"
  30. #include "include/bios_parser_interface.h"
  31. #include "include/i2caux_interface.h"
  32. #include "include/logger_interface.h"
  33. #include "command_table2.h"
  34. #include "bios_parser_helper.h"
  35. #include "command_table_helper2.h"
  36. #include "bios_parser2.h"
  37. #include "bios_parser_types_internal2.h"
  38. #include "bios_parser_interface.h"
  39. #include "bios_parser_common.h"
  40. #define LAST_RECORD_TYPE 0xff
  41. struct i2c_id_config_access {
  42. uint8_t bfI2C_LineMux:4;
  43. uint8_t bfHW_EngineID:3;
  44. uint8_t bfHW_Capable:1;
  45. uint8_t ucAccess;
  46. };
  47. static enum bp_result get_gpio_i2c_info(struct bios_parser *bp,
  48. struct atom_i2c_record *record,
  49. struct graphics_object_i2c_info *info);
  50. static enum bp_result bios_parser_get_firmware_info(
  51. struct dc_bios *dcb,
  52. struct dc_firmware_info *info);
  53. static enum bp_result bios_parser_get_encoder_cap_info(
  54. struct dc_bios *dcb,
  55. struct graphics_object_id object_id,
  56. struct bp_encoder_cap_info *info);
  57. static enum bp_result get_firmware_info_v3_1(
  58. struct bios_parser *bp,
  59. struct dc_firmware_info *info);
  60. static struct atom_hpd_int_record *get_hpd_record(struct bios_parser *bp,
  61. struct atom_display_object_path_v2 *object);
  62. static struct atom_encoder_caps_record *get_encoder_cap_record(
  63. struct bios_parser *bp,
  64. struct atom_display_object_path_v2 *object);
  65. #define BIOS_IMAGE_SIZE_OFFSET 2
  66. #define BIOS_IMAGE_SIZE_UNIT 512
  67. #define DATA_TABLES(table) (bp->master_data_tbl->listOfdatatables.table)
  68. static void destruct(struct bios_parser *bp)
  69. {
  70. kfree(bp->base.bios_local_image);
  71. kfree(bp->base.integrated_info);
  72. }
  73. static void firmware_parser_destroy(struct dc_bios **dcb)
  74. {
  75. struct bios_parser *bp = BP_FROM_DCB(*dcb);
  76. if (!bp) {
  77. BREAK_TO_DEBUGGER();
  78. return;
  79. }
  80. destruct(bp);
  81. kfree(bp);
  82. *dcb = NULL;
  83. }
  84. static void get_atom_data_table_revision(
  85. struct atom_common_table_header *atom_data_tbl,
  86. struct atom_data_revision *tbl_revision)
  87. {
  88. if (!tbl_revision)
  89. return;
  90. /* initialize the revision to 0 which is invalid revision */
  91. tbl_revision->major = 0;
  92. tbl_revision->minor = 0;
  93. if (!atom_data_tbl)
  94. return;
  95. tbl_revision->major =
  96. (uint32_t) atom_data_tbl->format_revision & 0x3f;
  97. tbl_revision->minor =
  98. (uint32_t) atom_data_tbl->content_revision & 0x3f;
  99. }
  100. /* BIOS oject table displaypath is per connector.
  101. * There is extra path not for connector. BIOS fill its encoderid as 0
  102. */
  103. static uint8_t bios_parser_get_connectors_number(struct dc_bios *dcb)
  104. {
  105. struct bios_parser *bp = BP_FROM_DCB(dcb);
  106. unsigned int count = 0;
  107. unsigned int i;
  108. for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
  109. if (bp->object_info_tbl.v1_4->display_path[i].encoderobjid != 0)
  110. count++;
  111. }
  112. return count;
  113. }
  114. static struct graphics_object_id bios_parser_get_encoder_id(
  115. struct dc_bios *dcb,
  116. uint32_t i)
  117. {
  118. struct bios_parser *bp = BP_FROM_DCB(dcb);
  119. struct graphics_object_id object_id = dal_graphics_object_id_init(
  120. 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN);
  121. if (bp->object_info_tbl.v1_4->number_of_path > i)
  122. object_id = object_id_from_bios_object_id(
  123. bp->object_info_tbl.v1_4->display_path[i].encoderobjid);
  124. return object_id;
  125. }
  126. static struct graphics_object_id bios_parser_get_connector_id(
  127. struct dc_bios *dcb,
  128. uint8_t i)
  129. {
  130. struct bios_parser *bp = BP_FROM_DCB(dcb);
  131. struct graphics_object_id object_id = dal_graphics_object_id_init(
  132. 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN);
  133. struct object_info_table *tbl = &bp->object_info_tbl;
  134. struct display_object_info_table_v1_4 *v1_4 = tbl->v1_4;
  135. if (v1_4->number_of_path > i) {
  136. /* If display_objid is generic object id, the encoderObj
  137. * /extencoderobjId should be 0
  138. */
  139. if (v1_4->display_path[i].encoderobjid != 0 &&
  140. v1_4->display_path[i].display_objid != 0)
  141. object_id = object_id_from_bios_object_id(
  142. v1_4->display_path[i].display_objid);
  143. }
  144. return object_id;
  145. }
  146. /* TODO: GetNumberOfSrc*/
  147. static uint32_t bios_parser_get_dst_number(struct dc_bios *dcb,
  148. struct graphics_object_id id)
  149. {
  150. /* connector has 1 Dest, encoder has 0 Dest */
  151. switch (id.type) {
  152. case OBJECT_TYPE_ENCODER:
  153. return 0;
  154. case OBJECT_TYPE_CONNECTOR:
  155. return 1;
  156. default:
  157. return 0;
  158. }
  159. }
  160. /* removed getSrcObjList, getDestObjList*/
  161. static enum bp_result bios_parser_get_src_obj(struct dc_bios *dcb,
  162. struct graphics_object_id object_id, uint32_t index,
  163. struct graphics_object_id *src_object_id)
  164. {
  165. struct bios_parser *bp = BP_FROM_DCB(dcb);
  166. unsigned int i;
  167. enum bp_result bp_result = BP_RESULT_BADINPUT;
  168. struct graphics_object_id obj_id = {0};
  169. struct object_info_table *tbl = &bp->object_info_tbl;
  170. if (!src_object_id)
  171. return bp_result;
  172. switch (object_id.type) {
  173. /* Encoder's Source is GPU. BIOS does not provide GPU, since all
  174. * displaypaths point to same GPU (0x1100). Hardcode GPU object type
  175. */
  176. case OBJECT_TYPE_ENCODER:
  177. /* TODO: since num of src must be less than 2.
  178. * If found in for loop, should break.
  179. * DAL2 implementation may be changed too
  180. */
  181. for (i = 0; i < tbl->v1_4->number_of_path; i++) {
  182. obj_id = object_id_from_bios_object_id(
  183. tbl->v1_4->display_path[i].encoderobjid);
  184. if (object_id.type == obj_id.type &&
  185. object_id.id == obj_id.id &&
  186. object_id.enum_id ==
  187. obj_id.enum_id) {
  188. *src_object_id =
  189. object_id_from_bios_object_id(0x1100);
  190. /* break; */
  191. }
  192. }
  193. bp_result = BP_RESULT_OK;
  194. break;
  195. case OBJECT_TYPE_CONNECTOR:
  196. for (i = 0; i < tbl->v1_4->number_of_path; i++) {
  197. obj_id = object_id_from_bios_object_id(
  198. tbl->v1_4->display_path[i].display_objid);
  199. if (object_id.type == obj_id.type &&
  200. object_id.id == obj_id.id &&
  201. object_id.enum_id == obj_id.enum_id) {
  202. *src_object_id =
  203. object_id_from_bios_object_id(
  204. tbl->v1_4->display_path[i].encoderobjid);
  205. /* break; */
  206. }
  207. }
  208. bp_result = BP_RESULT_OK;
  209. break;
  210. default:
  211. break;
  212. }
  213. return bp_result;
  214. }
  215. static enum bp_result bios_parser_get_dst_obj(struct dc_bios *dcb,
  216. struct graphics_object_id object_id, uint32_t index,
  217. struct graphics_object_id *dest_object_id)
  218. {
  219. struct bios_parser *bp = BP_FROM_DCB(dcb);
  220. unsigned int i;
  221. enum bp_result bp_result = BP_RESULT_BADINPUT;
  222. struct graphics_object_id obj_id = {0};
  223. struct object_info_table *tbl = &bp->object_info_tbl;
  224. if (!dest_object_id)
  225. return BP_RESULT_BADINPUT;
  226. switch (object_id.type) {
  227. case OBJECT_TYPE_ENCODER:
  228. /* TODO: since num of src must be less than 2.
  229. * If found in for loop, should break.
  230. * DAL2 implementation may be changed too
  231. */
  232. for (i = 0; i < tbl->v1_4->number_of_path; i++) {
  233. obj_id = object_id_from_bios_object_id(
  234. tbl->v1_4->display_path[i].encoderobjid);
  235. if (object_id.type == obj_id.type &&
  236. object_id.id == obj_id.id &&
  237. object_id.enum_id ==
  238. obj_id.enum_id) {
  239. *dest_object_id =
  240. object_id_from_bios_object_id(
  241. tbl->v1_4->display_path[i].display_objid);
  242. /* break; */
  243. }
  244. }
  245. bp_result = BP_RESULT_OK;
  246. break;
  247. default:
  248. break;
  249. }
  250. return bp_result;
  251. }
  252. /* from graphics_object_id, find display path which includes the object_id */
  253. static struct atom_display_object_path_v2 *get_bios_object(
  254. struct bios_parser *bp,
  255. struct graphics_object_id id)
  256. {
  257. unsigned int i;
  258. struct graphics_object_id obj_id = {0};
  259. switch (id.type) {
  260. case OBJECT_TYPE_ENCODER:
  261. for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
  262. obj_id = object_id_from_bios_object_id(
  263. bp->object_info_tbl.v1_4->display_path[i].encoderobjid);
  264. if (id.type == obj_id.type &&
  265. id.id == obj_id.id &&
  266. id.enum_id == obj_id.enum_id)
  267. return
  268. &bp->object_info_tbl.v1_4->display_path[i];
  269. }
  270. case OBJECT_TYPE_CONNECTOR:
  271. case OBJECT_TYPE_GENERIC:
  272. /* Both Generic and Connector Object ID
  273. * will be stored on display_objid
  274. */
  275. for (i = 0; i < bp->object_info_tbl.v1_4->number_of_path; i++) {
  276. obj_id = object_id_from_bios_object_id(
  277. bp->object_info_tbl.v1_4->display_path[i].display_objid
  278. );
  279. if (id.type == obj_id.type &&
  280. id.id == obj_id.id &&
  281. id.enum_id == obj_id.enum_id)
  282. return
  283. &bp->object_info_tbl.v1_4->display_path[i];
  284. }
  285. default:
  286. return NULL;
  287. }
  288. }
  289. static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,
  290. struct graphics_object_id id,
  291. struct graphics_object_i2c_info *info)
  292. {
  293. uint32_t offset;
  294. struct atom_display_object_path_v2 *object;
  295. struct atom_common_record_header *header;
  296. struct atom_i2c_record *record;
  297. struct bios_parser *bp = BP_FROM_DCB(dcb);
  298. if (!info)
  299. return BP_RESULT_BADINPUT;
  300. object = get_bios_object(bp, id);
  301. if (!object)
  302. return BP_RESULT_BADINPUT;
  303. offset = object->disp_recordoffset + bp->object_info_tbl_offset;
  304. for (;;) {
  305. header = GET_IMAGE(struct atom_common_record_header, offset);
  306. if (!header)
  307. return BP_RESULT_BADBIOSTABLE;
  308. if (header->record_type == LAST_RECORD_TYPE ||
  309. !header->record_size)
  310. break;
  311. if (header->record_type == ATOM_I2C_RECORD_TYPE
  312. && sizeof(struct atom_i2c_record) <=
  313. header->record_size) {
  314. /* get the I2C info */
  315. record = (struct atom_i2c_record *) header;
  316. if (get_gpio_i2c_info(bp, record, info) ==
  317. BP_RESULT_OK)
  318. return BP_RESULT_OK;
  319. }
  320. offset += header->record_size;
  321. }
  322. return BP_RESULT_NORECORD;
  323. }
  324. static enum bp_result get_gpio_i2c_info(
  325. struct bios_parser *bp,
  326. struct atom_i2c_record *record,
  327. struct graphics_object_i2c_info *info)
  328. {
  329. struct atom_gpio_pin_lut_v2_1 *header;
  330. uint32_t count = 0;
  331. unsigned int table_index = 0;
  332. if (!info)
  333. return BP_RESULT_BADINPUT;
  334. /* get the GPIO_I2C info */
  335. if (!DATA_TABLES(gpio_pin_lut))
  336. return BP_RESULT_BADBIOSTABLE;
  337. header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1,
  338. DATA_TABLES(gpio_pin_lut));
  339. if (!header)
  340. return BP_RESULT_BADBIOSTABLE;
  341. if (sizeof(struct atom_common_table_header) +
  342. sizeof(struct atom_gpio_pin_assignment) >
  343. le16_to_cpu(header->table_header.structuresize))
  344. return BP_RESULT_BADBIOSTABLE;
  345. /* TODO: is version change? */
  346. if (header->table_header.content_revision != 1)
  347. return BP_RESULT_UNSUPPORTED;
  348. /* get data count */
  349. count = (le16_to_cpu(header->table_header.structuresize)
  350. - sizeof(struct atom_common_table_header))
  351. / sizeof(struct atom_gpio_pin_assignment);
  352. table_index = record->i2c_id & I2C_HW_LANE_MUX;
  353. if (count < table_index) {
  354. bool find_valid = false;
  355. for (table_index = 0; table_index < count; table_index++) {
  356. if (((record->i2c_id & I2C_HW_CAP) == (
  357. header->gpio_pin[table_index].gpio_id &
  358. I2C_HW_CAP)) &&
  359. ((record->i2c_id & I2C_HW_ENGINE_ID_MASK) ==
  360. (header->gpio_pin[table_index].gpio_id &
  361. I2C_HW_ENGINE_ID_MASK)) &&
  362. ((record->i2c_id & I2C_HW_LANE_MUX) ==
  363. (header->gpio_pin[table_index].gpio_id &
  364. I2C_HW_LANE_MUX))) {
  365. /* still valid */
  366. find_valid = true;
  367. break;
  368. }
  369. }
  370. /* If we don't find the entry that we are looking for then
  371. * we will return BP_Result_BadBiosTable.
  372. */
  373. if (find_valid == false)
  374. return BP_RESULT_BADBIOSTABLE;
  375. }
  376. /* get the GPIO_I2C_INFO */
  377. info->i2c_hw_assist = (record->i2c_id & I2C_HW_CAP) ? true : false;
  378. info->i2c_line = record->i2c_id & I2C_HW_LANE_MUX;
  379. info->i2c_engine_id = (record->i2c_id & I2C_HW_ENGINE_ID_MASK) >> 4;
  380. info->i2c_slave_address = record->i2c_slave_addr;
  381. /* TODO: check how to get register offset for en, Y, etc. */
  382. info->gpio_info.clk_a_register_index =
  383. le16_to_cpu(
  384. header->gpio_pin[table_index].data_a_reg_index);
  385. info->gpio_info.clk_a_shift =
  386. header->gpio_pin[table_index].gpio_bitshift;
  387. return BP_RESULT_OK;
  388. }
  389. static enum bp_result get_voltage_ddc_info_v4(
  390. uint8_t *i2c_line,
  391. uint32_t index,
  392. struct atom_common_table_header *header,
  393. uint8_t *address)
  394. {
  395. enum bp_result result = BP_RESULT_NORECORD;
  396. struct atom_voltage_objects_info_v4_1 *info =
  397. (struct atom_voltage_objects_info_v4_1 *) address;
  398. uint8_t *voltage_current_object =
  399. (uint8_t *) (&(info->voltage_object[0]));
  400. while ((address + le16_to_cpu(header->structuresize)) >
  401. voltage_current_object) {
  402. struct atom_i2c_voltage_object_v4 *object =
  403. (struct atom_i2c_voltage_object_v4 *)
  404. voltage_current_object;
  405. if (object->header.voltage_mode ==
  406. ATOM_INIT_VOLTAGE_REGULATOR) {
  407. if (object->header.voltage_type == index) {
  408. *i2c_line = object->i2c_id ^ 0x90;
  409. result = BP_RESULT_OK;
  410. break;
  411. }
  412. }
  413. voltage_current_object +=
  414. le16_to_cpu(object->header.object_size);
  415. }
  416. return result;
  417. }
  418. static enum bp_result bios_parser_get_thermal_ddc_info(
  419. struct dc_bios *dcb,
  420. uint32_t i2c_channel_id,
  421. struct graphics_object_i2c_info *info)
  422. {
  423. struct bios_parser *bp = BP_FROM_DCB(dcb);
  424. struct i2c_id_config_access *config;
  425. struct atom_i2c_record record;
  426. if (!info)
  427. return BP_RESULT_BADINPUT;
  428. config = (struct i2c_id_config_access *) &i2c_channel_id;
  429. record.i2c_id = config->bfHW_Capable;
  430. record.i2c_id |= config->bfI2C_LineMux;
  431. record.i2c_id |= config->bfHW_EngineID;
  432. return get_gpio_i2c_info(bp, &record, info);
  433. }
  434. static enum bp_result bios_parser_get_voltage_ddc_info(struct dc_bios *dcb,
  435. uint32_t index,
  436. struct graphics_object_i2c_info *info)
  437. {
  438. uint8_t i2c_line = 0;
  439. enum bp_result result = BP_RESULT_NORECORD;
  440. uint8_t *voltage_info_address;
  441. struct atom_common_table_header *header;
  442. struct atom_data_revision revision = {0};
  443. struct bios_parser *bp = BP_FROM_DCB(dcb);
  444. if (!DATA_TABLES(voltageobject_info))
  445. return result;
  446. voltage_info_address = bios_get_image(&bp->base,
  447. DATA_TABLES(voltageobject_info),
  448. sizeof(struct atom_common_table_header));
  449. header = (struct atom_common_table_header *) voltage_info_address;
  450. get_atom_data_table_revision(header, &revision);
  451. switch (revision.major) {
  452. case 4:
  453. if (revision.minor != 1)
  454. break;
  455. result = get_voltage_ddc_info_v4(&i2c_line, index, header,
  456. voltage_info_address);
  457. break;
  458. }
  459. if (result == BP_RESULT_OK)
  460. result = bios_parser_get_thermal_ddc_info(dcb,
  461. i2c_line, info);
  462. return result;
  463. }
  464. static enum bp_result bios_parser_get_hpd_info(
  465. struct dc_bios *dcb,
  466. struct graphics_object_id id,
  467. struct graphics_object_hpd_info *info)
  468. {
  469. struct bios_parser *bp = BP_FROM_DCB(dcb);
  470. struct atom_display_object_path_v2 *object;
  471. struct atom_hpd_int_record *record = NULL;
  472. if (!info)
  473. return BP_RESULT_BADINPUT;
  474. object = get_bios_object(bp, id);
  475. if (!object)
  476. return BP_RESULT_BADINPUT;
  477. record = get_hpd_record(bp, object);
  478. if (record != NULL) {
  479. info->hpd_int_gpio_uid = record->pin_id;
  480. info->hpd_active = record->plugin_pin_state;
  481. return BP_RESULT_OK;
  482. }
  483. return BP_RESULT_NORECORD;
  484. }
  485. static struct atom_hpd_int_record *get_hpd_record(
  486. struct bios_parser *bp,
  487. struct atom_display_object_path_v2 *object)
  488. {
  489. struct atom_common_record_header *header;
  490. uint32_t offset;
  491. if (!object) {
  492. BREAK_TO_DEBUGGER(); /* Invalid object */
  493. return NULL;
  494. }
  495. offset = le16_to_cpu(object->disp_recordoffset)
  496. + bp->object_info_tbl_offset;
  497. for (;;) {
  498. header = GET_IMAGE(struct atom_common_record_header, offset);
  499. if (!header)
  500. return NULL;
  501. if (header->record_type == LAST_RECORD_TYPE ||
  502. !header->record_size)
  503. break;
  504. if (header->record_type == ATOM_HPD_INT_RECORD_TYPE
  505. && sizeof(struct atom_hpd_int_record) <=
  506. header->record_size)
  507. return (struct atom_hpd_int_record *) header;
  508. offset += header->record_size;
  509. }
  510. return NULL;
  511. }
  512. /**
  513. * bios_parser_get_gpio_pin_info
  514. * Get GpioPin information of input gpio id
  515. *
  516. * @param gpio_id, GPIO ID
  517. * @param info, GpioPin information structure
  518. * @return Bios parser result code
  519. * @note
  520. * to get the GPIO PIN INFO, we need:
  521. * 1. get the GPIO_ID from other object table, see GetHPDInfo()
  522. * 2. in DATA_TABLE.GPIO_Pin_LUT, search all records,
  523. * to get the registerA offset/mask
  524. */
  525. static enum bp_result bios_parser_get_gpio_pin_info(
  526. struct dc_bios *dcb,
  527. uint32_t gpio_id,
  528. struct gpio_pin_info *info)
  529. {
  530. struct bios_parser *bp = BP_FROM_DCB(dcb);
  531. struct atom_gpio_pin_lut_v2_1 *header;
  532. uint32_t count = 0;
  533. uint32_t i = 0;
  534. if (!DATA_TABLES(gpio_pin_lut))
  535. return BP_RESULT_BADBIOSTABLE;
  536. header = GET_IMAGE(struct atom_gpio_pin_lut_v2_1,
  537. DATA_TABLES(gpio_pin_lut));
  538. if (!header)
  539. return BP_RESULT_BADBIOSTABLE;
  540. if (sizeof(struct atom_common_table_header) +
  541. sizeof(struct atom_gpio_pin_lut_v2_1)
  542. > le16_to_cpu(header->table_header.structuresize))
  543. return BP_RESULT_BADBIOSTABLE;
  544. if (header->table_header.content_revision != 1)
  545. return BP_RESULT_UNSUPPORTED;
  546. /* Temporary hard code gpio pin info */
  547. #if defined(FOR_SIMNOW_BOOT)
  548. {
  549. struct atom_gpio_pin_assignment gpio_pin[8] = {
  550. {0x5db5, 0, 0, 1, 0},
  551. {0x5db5, 8, 8, 2, 0},
  552. {0x5db5, 0x10, 0x10, 3, 0},
  553. {0x5db5, 0x18, 0x14, 4, 0},
  554. {0x5db5, 0x1A, 0x18, 5, 0},
  555. {0x5db5, 0x1C, 0x1C, 6, 0},
  556. };
  557. count = 6;
  558. memmove(header->gpio_pin, gpio_pin, sizeof(gpio_pin));
  559. }
  560. #else
  561. count = (le16_to_cpu(header->table_header.structuresize)
  562. - sizeof(struct atom_common_table_header))
  563. / sizeof(struct atom_gpio_pin_assignment);
  564. #endif
  565. for (i = 0; i < count; ++i) {
  566. if (header->gpio_pin[i].gpio_id != gpio_id)
  567. continue;
  568. info->offset =
  569. (uint32_t) le16_to_cpu(
  570. header->gpio_pin[i].data_a_reg_index);
  571. info->offset_y = info->offset + 2;
  572. info->offset_en = info->offset + 1;
  573. info->offset_mask = info->offset - 1;
  574. info->mask = (uint32_t) (1 <<
  575. header->gpio_pin[i].gpio_bitshift);
  576. info->mask_y = info->mask + 2;
  577. info->mask_en = info->mask + 1;
  578. info->mask_mask = info->mask - 1;
  579. return BP_RESULT_OK;
  580. }
  581. return BP_RESULT_NORECORD;
  582. }
  583. static struct device_id device_type_from_device_id(uint16_t device_id)
  584. {
  585. struct device_id result_device_id;
  586. result_device_id.raw_device_tag = device_id;
  587. switch (device_id) {
  588. case ATOM_DISPLAY_LCD1_SUPPORT:
  589. result_device_id.device_type = DEVICE_TYPE_LCD;
  590. result_device_id.enum_id = 1;
  591. break;
  592. case ATOM_DISPLAY_DFP1_SUPPORT:
  593. result_device_id.device_type = DEVICE_TYPE_DFP;
  594. result_device_id.enum_id = 1;
  595. break;
  596. case ATOM_DISPLAY_DFP2_SUPPORT:
  597. result_device_id.device_type = DEVICE_TYPE_DFP;
  598. result_device_id.enum_id = 2;
  599. break;
  600. case ATOM_DISPLAY_DFP3_SUPPORT:
  601. result_device_id.device_type = DEVICE_TYPE_DFP;
  602. result_device_id.enum_id = 3;
  603. break;
  604. case ATOM_DISPLAY_DFP4_SUPPORT:
  605. result_device_id.device_type = DEVICE_TYPE_DFP;
  606. result_device_id.enum_id = 4;
  607. break;
  608. case ATOM_DISPLAY_DFP5_SUPPORT:
  609. result_device_id.device_type = DEVICE_TYPE_DFP;
  610. result_device_id.enum_id = 5;
  611. break;
  612. case ATOM_DISPLAY_DFP6_SUPPORT:
  613. result_device_id.device_type = DEVICE_TYPE_DFP;
  614. result_device_id.enum_id = 6;
  615. break;
  616. default:
  617. BREAK_TO_DEBUGGER(); /* Invalid device Id */
  618. result_device_id.device_type = DEVICE_TYPE_UNKNOWN;
  619. result_device_id.enum_id = 0;
  620. }
  621. return result_device_id;
  622. }
  623. static enum bp_result bios_parser_get_device_tag(
  624. struct dc_bios *dcb,
  625. struct graphics_object_id connector_object_id,
  626. uint32_t device_tag_index,
  627. struct connector_device_tag_info *info)
  628. {
  629. struct bios_parser *bp = BP_FROM_DCB(dcb);
  630. struct atom_display_object_path_v2 *object;
  631. if (!info)
  632. return BP_RESULT_BADINPUT;
  633. /* getBiosObject will return MXM object */
  634. object = get_bios_object(bp, connector_object_id);
  635. if (!object) {
  636. BREAK_TO_DEBUGGER(); /* Invalid object id */
  637. return BP_RESULT_BADINPUT;
  638. }
  639. info->acpi_device = 0; /* BIOS no longer provides this */
  640. info->dev_id = device_type_from_device_id(object->device_tag);
  641. return BP_RESULT_OK;
  642. }
  643. static enum bp_result get_ss_info_v4_1(
  644. struct bios_parser *bp,
  645. uint32_t id,
  646. uint32_t index,
  647. struct spread_spectrum_info *ss_info)
  648. {
  649. enum bp_result result = BP_RESULT_OK;
  650. struct atom_display_controller_info_v4_1 *disp_cntl_tbl = NULL;
  651. if (!ss_info)
  652. return BP_RESULT_BADINPUT;
  653. if (!DATA_TABLES(dce_info))
  654. return BP_RESULT_BADBIOSTABLE;
  655. disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_1,
  656. DATA_TABLES(dce_info));
  657. if (!disp_cntl_tbl)
  658. return BP_RESULT_BADBIOSTABLE;
  659. ss_info->type.STEP_AND_DELAY_INFO = false;
  660. ss_info->spread_percentage_divider = 1000;
  661. /* BIOS no longer uses target clock. Always enable for now */
  662. ss_info->target_clock_range = 0xffffffff;
  663. switch (id) {
  664. case AS_SIGNAL_TYPE_DVI:
  665. ss_info->spread_spectrum_percentage =
  666. disp_cntl_tbl->dvi_ss_percentage;
  667. ss_info->spread_spectrum_range =
  668. disp_cntl_tbl->dvi_ss_rate_10hz * 10;
  669. if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
  670. ss_info->type.CENTER_MODE = true;
  671. break;
  672. case AS_SIGNAL_TYPE_HDMI:
  673. ss_info->spread_spectrum_percentage =
  674. disp_cntl_tbl->hdmi_ss_percentage;
  675. ss_info->spread_spectrum_range =
  676. disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
  677. if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
  678. ss_info->type.CENTER_MODE = true;
  679. break;
  680. /* TODO LVDS not support anymore? */
  681. case AS_SIGNAL_TYPE_DISPLAY_PORT:
  682. ss_info->spread_spectrum_percentage =
  683. disp_cntl_tbl->dp_ss_percentage;
  684. ss_info->spread_spectrum_range =
  685. disp_cntl_tbl->dp_ss_rate_10hz * 10;
  686. if (disp_cntl_tbl->dp_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
  687. ss_info->type.CENTER_MODE = true;
  688. break;
  689. case AS_SIGNAL_TYPE_GPU_PLL:
  690. /* atom_firmware: DAL only get data from dce_info table.
  691. * if data within smu_info is needed for DAL, VBIOS should
  692. * copy it into dce_info
  693. */
  694. result = BP_RESULT_UNSUPPORTED;
  695. break;
  696. default:
  697. result = BP_RESULT_UNSUPPORTED;
  698. }
  699. return result;
  700. }
  701. static enum bp_result get_ss_info_v4_2(
  702. struct bios_parser *bp,
  703. uint32_t id,
  704. uint32_t index,
  705. struct spread_spectrum_info *ss_info)
  706. {
  707. enum bp_result result = BP_RESULT_OK;
  708. struct atom_display_controller_info_v4_2 *disp_cntl_tbl = NULL;
  709. struct atom_smu_info_v3_1 *smu_info = NULL;
  710. if (!ss_info)
  711. return BP_RESULT_BADINPUT;
  712. if (!DATA_TABLES(dce_info))
  713. return BP_RESULT_BADBIOSTABLE;
  714. if (!DATA_TABLES(smu_info))
  715. return BP_RESULT_BADBIOSTABLE;
  716. disp_cntl_tbl = GET_IMAGE(struct atom_display_controller_info_v4_2,
  717. DATA_TABLES(dce_info));
  718. if (!disp_cntl_tbl)
  719. return BP_RESULT_BADBIOSTABLE;
  720. smu_info = GET_IMAGE(struct atom_smu_info_v3_1, DATA_TABLES(smu_info));
  721. if (!smu_info)
  722. return BP_RESULT_BADBIOSTABLE;
  723. ss_info->type.STEP_AND_DELAY_INFO = false;
  724. ss_info->spread_percentage_divider = 1000;
  725. /* BIOS no longer uses target clock. Always enable for now */
  726. ss_info->target_clock_range = 0xffffffff;
  727. switch (id) {
  728. case AS_SIGNAL_TYPE_DVI:
  729. ss_info->spread_spectrum_percentage =
  730. disp_cntl_tbl->dvi_ss_percentage;
  731. ss_info->spread_spectrum_range =
  732. disp_cntl_tbl->dvi_ss_rate_10hz * 10;
  733. if (disp_cntl_tbl->dvi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
  734. ss_info->type.CENTER_MODE = true;
  735. break;
  736. case AS_SIGNAL_TYPE_HDMI:
  737. ss_info->spread_spectrum_percentage =
  738. disp_cntl_tbl->hdmi_ss_percentage;
  739. ss_info->spread_spectrum_range =
  740. disp_cntl_tbl->hdmi_ss_rate_10hz * 10;
  741. if (disp_cntl_tbl->hdmi_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
  742. ss_info->type.CENTER_MODE = true;
  743. break;
  744. /* TODO LVDS not support anymore? */
  745. case AS_SIGNAL_TYPE_DISPLAY_PORT:
  746. ss_info->spread_spectrum_percentage =
  747. smu_info->gpuclk_ss_percentage;
  748. ss_info->spread_spectrum_range =
  749. smu_info->gpuclk_ss_rate_10hz * 10;
  750. if (smu_info->gpuclk_ss_mode & ATOM_SS_CENTRE_SPREAD_MODE)
  751. ss_info->type.CENTER_MODE = true;
  752. break;
  753. case AS_SIGNAL_TYPE_GPU_PLL:
  754. /* atom_firmware: DAL only get data from dce_info table.
  755. * if data within smu_info is needed for DAL, VBIOS should
  756. * copy it into dce_info
  757. */
  758. result = BP_RESULT_UNSUPPORTED;
  759. break;
  760. default:
  761. result = BP_RESULT_UNSUPPORTED;
  762. }
  763. return result;
  764. }
  765. /**
  766. * bios_parser_get_spread_spectrum_info
  767. * Get spread spectrum information from the ASIC_InternalSS_Info(ver 2.1 or
  768. * ver 3.1) or SS_Info table from the VBIOS. Currently ASIC_InternalSS_Info
  769. * ver 2.1 can co-exist with SS_Info table. Expect ASIC_InternalSS_Info
  770. * ver 3.1,
  771. * there is only one entry for each signal /ss id. However, there is
  772. * no planning of supporting multiple spread Sprectum entry for EverGreen
  773. * @param [in] this
  774. * @param [in] signal, ASSignalType to be converted to info index
  775. * @param [in] index, number of entries that match the converted info index
  776. * @param [out] ss_info, sprectrum information structure,
  777. * @return Bios parser result code
  778. */
  779. static enum bp_result bios_parser_get_spread_spectrum_info(
  780. struct dc_bios *dcb,
  781. enum as_signal_type signal,
  782. uint32_t index,
  783. struct spread_spectrum_info *ss_info)
  784. {
  785. struct bios_parser *bp = BP_FROM_DCB(dcb);
  786. enum bp_result result = BP_RESULT_UNSUPPORTED;
  787. struct atom_common_table_header *header;
  788. struct atom_data_revision tbl_revision;
  789. if (!ss_info) /* check for bad input */
  790. return BP_RESULT_BADINPUT;
  791. if (!DATA_TABLES(dce_info))
  792. return BP_RESULT_UNSUPPORTED;
  793. header = GET_IMAGE(struct atom_common_table_header,
  794. DATA_TABLES(dce_info));
  795. get_atom_data_table_revision(header, &tbl_revision);
  796. switch (tbl_revision.major) {
  797. case 4:
  798. switch (tbl_revision.minor) {
  799. case 1:
  800. return get_ss_info_v4_1(bp, signal, index, ss_info);
  801. case 2:
  802. return get_ss_info_v4_2(bp, signal, index, ss_info);
  803. default:
  804. break;
  805. }
  806. break;
  807. default:
  808. break;
  809. }
  810. /* there can not be more then one entry for SS Info table */
  811. return result;
  812. }
  813. static enum bp_result get_embedded_panel_info_v2_1(
  814. struct bios_parser *bp,
  815. struct embedded_panel_info *info)
  816. {
  817. struct lcd_info_v2_1 *lvds;
  818. if (!info)
  819. return BP_RESULT_BADINPUT;
  820. if (!DATA_TABLES(lcd_info))
  821. return BP_RESULT_UNSUPPORTED;
  822. lvds = GET_IMAGE(struct lcd_info_v2_1, DATA_TABLES(lcd_info));
  823. if (!lvds)
  824. return BP_RESULT_BADBIOSTABLE;
  825. /* TODO: previous vv1_3, should v2_1 */
  826. if (!((lvds->table_header.format_revision == 2)
  827. && (lvds->table_header.content_revision >= 1)))
  828. return BP_RESULT_UNSUPPORTED;
  829. memset(info, 0, sizeof(struct embedded_panel_info));
  830. /* We need to convert from 10KHz units into KHz units */
  831. info->lcd_timing.pixel_clk =
  832. le16_to_cpu(lvds->lcd_timing.pixclk) * 10;
  833. /* usHActive does not include borders, according to VBIOS team */
  834. info->lcd_timing.horizontal_addressable =
  835. le16_to_cpu(lvds->lcd_timing.h_active);
  836. /* usHBlanking_Time includes borders, so we should really be
  837. * subtractingborders duing this translation, but LVDS generally
  838. * doesn't have borders, so we should be okay leaving this as is for
  839. * now. May need to revisit if we ever have LVDS with borders
  840. */
  841. info->lcd_timing.horizontal_blanking_time =
  842. le16_to_cpu(lvds->lcd_timing.h_blanking_time);
  843. /* usVActive does not include borders, according to VBIOS team*/
  844. info->lcd_timing.vertical_addressable =
  845. le16_to_cpu(lvds->lcd_timing.v_active);
  846. /* usVBlanking_Time includes borders, so we should really be
  847. * subtracting borders duing this translation, but LVDS generally
  848. * doesn't have borders, so we should be okay leaving this as is for
  849. * now. May need to revisit if we ever have LVDS with borders
  850. */
  851. info->lcd_timing.vertical_blanking_time =
  852. le16_to_cpu(lvds->lcd_timing.v_blanking_time);
  853. info->lcd_timing.horizontal_sync_offset =
  854. le16_to_cpu(lvds->lcd_timing.h_sync_offset);
  855. info->lcd_timing.horizontal_sync_width =
  856. le16_to_cpu(lvds->lcd_timing.h_sync_width);
  857. info->lcd_timing.vertical_sync_offset =
  858. le16_to_cpu(lvds->lcd_timing.v_sync_offset);
  859. info->lcd_timing.vertical_sync_width =
  860. le16_to_cpu(lvds->lcd_timing.v_syncwidth);
  861. info->lcd_timing.horizontal_border = lvds->lcd_timing.h_border;
  862. info->lcd_timing.vertical_border = lvds->lcd_timing.v_border;
  863. /* not provided by VBIOS */
  864. info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0;
  865. info->lcd_timing.misc_info.H_SYNC_POLARITY =
  866. ~(uint32_t)
  867. (lvds->lcd_timing.miscinfo & ATOM_HSYNC_POLARITY);
  868. info->lcd_timing.misc_info.V_SYNC_POLARITY =
  869. ~(uint32_t)
  870. (lvds->lcd_timing.miscinfo & ATOM_VSYNC_POLARITY);
  871. /* not provided by VBIOS */
  872. info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0;
  873. info->lcd_timing.misc_info.H_REPLICATION_BY2 =
  874. !!(lvds->lcd_timing.miscinfo & ATOM_H_REPLICATIONBY2);
  875. info->lcd_timing.misc_info.V_REPLICATION_BY2 =
  876. !!(lvds->lcd_timing.miscinfo & ATOM_V_REPLICATIONBY2);
  877. info->lcd_timing.misc_info.COMPOSITE_SYNC =
  878. !!(lvds->lcd_timing.miscinfo & ATOM_COMPOSITESYNC);
  879. info->lcd_timing.misc_info.INTERLACE =
  880. !!(lvds->lcd_timing.miscinfo & ATOM_INTERLACE);
  881. /* not provided by VBIOS*/
  882. info->lcd_timing.misc_info.DOUBLE_CLOCK = 0;
  883. /* not provided by VBIOS*/
  884. info->ss_id = 0;
  885. info->realtek_eDPToLVDS =
  886. !!(lvds->dplvdsrxid == eDP_TO_LVDS_REALTEK_ID);
  887. return BP_RESULT_OK;
  888. }
  889. static enum bp_result bios_parser_get_embedded_panel_info(
  890. struct dc_bios *dcb,
  891. struct embedded_panel_info *info)
  892. {
  893. struct bios_parser *bp = BP_FROM_DCB(dcb);
  894. struct atom_common_table_header *header;
  895. struct atom_data_revision tbl_revision;
  896. if (!DATA_TABLES(lcd_info))
  897. return BP_RESULT_FAILURE;
  898. header = GET_IMAGE(struct atom_common_table_header,
  899. DATA_TABLES(lcd_info));
  900. if (!header)
  901. return BP_RESULT_BADBIOSTABLE;
  902. get_atom_data_table_revision(header, &tbl_revision);
  903. switch (tbl_revision.major) {
  904. case 2:
  905. switch (tbl_revision.minor) {
  906. case 1:
  907. return get_embedded_panel_info_v2_1(bp, info);
  908. default:
  909. break;
  910. }
  911. default:
  912. break;
  913. }
  914. return BP_RESULT_FAILURE;
  915. }
  916. static uint32_t get_support_mask_for_device_id(struct device_id device_id)
  917. {
  918. enum dal_device_type device_type = device_id.device_type;
  919. uint32_t enum_id = device_id.enum_id;
  920. switch (device_type) {
  921. case DEVICE_TYPE_LCD:
  922. switch (enum_id) {
  923. case 1:
  924. return ATOM_DISPLAY_LCD1_SUPPORT;
  925. default:
  926. break;
  927. }
  928. break;
  929. case DEVICE_TYPE_DFP:
  930. switch (enum_id) {
  931. case 1:
  932. return ATOM_DISPLAY_DFP1_SUPPORT;
  933. case 2:
  934. return ATOM_DISPLAY_DFP2_SUPPORT;
  935. case 3:
  936. return ATOM_DISPLAY_DFP3_SUPPORT;
  937. case 4:
  938. return ATOM_DISPLAY_DFP4_SUPPORT;
  939. case 5:
  940. return ATOM_DISPLAY_DFP5_SUPPORT;
  941. case 6:
  942. return ATOM_DISPLAY_DFP6_SUPPORT;
  943. default:
  944. break;
  945. }
  946. break;
  947. default:
  948. break;
  949. };
  950. /* Unidentified device ID, return empty support mask. */
  951. return 0;
  952. }
  953. static bool bios_parser_is_device_id_supported(
  954. struct dc_bios *dcb,
  955. struct device_id id)
  956. {
  957. struct bios_parser *bp = BP_FROM_DCB(dcb);
  958. uint32_t mask = get_support_mask_for_device_id(id);
  959. return (le16_to_cpu(bp->object_info_tbl.v1_4->supporteddevices) &
  960. mask) != 0;
  961. }
  962. static void bios_parser_post_init(
  963. struct dc_bios *dcb)
  964. {
  965. /* TODO for OPM module. Need implement later */
  966. }
  967. static uint32_t bios_parser_get_ss_entry_number(
  968. struct dc_bios *dcb,
  969. enum as_signal_type signal)
  970. {
  971. /* TODO: DAL2 atomfirmware implementation does not need this.
  972. * why DAL3 need this?
  973. */
  974. return 1;
  975. }
  976. static enum bp_result bios_parser_transmitter_control(
  977. struct dc_bios *dcb,
  978. struct bp_transmitter_control *cntl)
  979. {
  980. struct bios_parser *bp = BP_FROM_DCB(dcb);
  981. if (!bp->cmd_tbl.transmitter_control)
  982. return BP_RESULT_FAILURE;
  983. return bp->cmd_tbl.transmitter_control(bp, cntl);
  984. }
  985. static enum bp_result bios_parser_encoder_control(
  986. struct dc_bios *dcb,
  987. struct bp_encoder_control *cntl)
  988. {
  989. struct bios_parser *bp = BP_FROM_DCB(dcb);
  990. if (!bp->cmd_tbl.dig_encoder_control)
  991. return BP_RESULT_FAILURE;
  992. return bp->cmd_tbl.dig_encoder_control(bp, cntl);
  993. }
  994. static enum bp_result bios_parser_set_pixel_clock(
  995. struct dc_bios *dcb,
  996. struct bp_pixel_clock_parameters *bp_params)
  997. {
  998. struct bios_parser *bp = BP_FROM_DCB(dcb);
  999. if (!bp->cmd_tbl.set_pixel_clock)
  1000. return BP_RESULT_FAILURE;
  1001. return bp->cmd_tbl.set_pixel_clock(bp, bp_params);
  1002. }
  1003. static enum bp_result bios_parser_set_dce_clock(
  1004. struct dc_bios *dcb,
  1005. struct bp_set_dce_clock_parameters *bp_params)
  1006. {
  1007. struct bios_parser *bp = BP_FROM_DCB(dcb);
  1008. if (!bp->cmd_tbl.set_dce_clock)
  1009. return BP_RESULT_FAILURE;
  1010. return bp->cmd_tbl.set_dce_clock(bp, bp_params);
  1011. }
  1012. static unsigned int bios_parser_get_smu_clock_info(
  1013. struct dc_bios *dcb)
  1014. {
  1015. struct bios_parser *bp = BP_FROM_DCB(dcb);
  1016. if (!bp->cmd_tbl.get_smu_clock_info)
  1017. return BP_RESULT_FAILURE;
  1018. return bp->cmd_tbl.get_smu_clock_info(bp);
  1019. }
  1020. static enum bp_result bios_parser_program_crtc_timing(
  1021. struct dc_bios *dcb,
  1022. struct bp_hw_crtc_timing_parameters *bp_params)
  1023. {
  1024. struct bios_parser *bp = BP_FROM_DCB(dcb);
  1025. if (!bp->cmd_tbl.set_crtc_timing)
  1026. return BP_RESULT_FAILURE;
  1027. return bp->cmd_tbl.set_crtc_timing(bp, bp_params);
  1028. }
  1029. static enum bp_result bios_parser_enable_crtc(
  1030. struct dc_bios *dcb,
  1031. enum controller_id id,
  1032. bool enable)
  1033. {
  1034. struct bios_parser *bp = BP_FROM_DCB(dcb);
  1035. if (!bp->cmd_tbl.enable_crtc)
  1036. return BP_RESULT_FAILURE;
  1037. return bp->cmd_tbl.enable_crtc(bp, id, enable);
  1038. }
  1039. static enum bp_result bios_parser_crtc_source_select(
  1040. struct dc_bios *dcb,
  1041. struct bp_crtc_source_select *bp_params)
  1042. {
  1043. struct bios_parser *bp = BP_FROM_DCB(dcb);
  1044. if (!bp->cmd_tbl.select_crtc_source)
  1045. return BP_RESULT_FAILURE;
  1046. return bp->cmd_tbl.select_crtc_source(bp, bp_params);
  1047. }
  1048. static enum bp_result bios_parser_enable_disp_power_gating(
  1049. struct dc_bios *dcb,
  1050. enum controller_id controller_id,
  1051. enum bp_pipe_control_action action)
  1052. {
  1053. struct bios_parser *bp = BP_FROM_DCB(dcb);
  1054. if (!bp->cmd_tbl.enable_disp_power_gating)
  1055. return BP_RESULT_FAILURE;
  1056. return bp->cmd_tbl.enable_disp_power_gating(bp, controller_id,
  1057. action);
  1058. }
  1059. static bool bios_parser_is_accelerated_mode(
  1060. struct dc_bios *dcb)
  1061. {
  1062. return bios_is_accelerated_mode(dcb);
  1063. }
  1064. /**
  1065. * bios_parser_set_scratch_critical_state
  1066. *
  1067. * @brief
  1068. * update critical state bit in VBIOS scratch register
  1069. *
  1070. * @param
  1071. * bool - to set or reset state
  1072. */
  1073. static void bios_parser_set_scratch_critical_state(
  1074. struct dc_bios *dcb,
  1075. bool state)
  1076. {
  1077. bios_set_scratch_critical_state(dcb, state);
  1078. }
  1079. static enum bp_result bios_parser_get_firmware_info(
  1080. struct dc_bios *dcb,
  1081. struct dc_firmware_info *info)
  1082. {
  1083. struct bios_parser *bp = BP_FROM_DCB(dcb);
  1084. enum bp_result result = BP_RESULT_BADBIOSTABLE;
  1085. struct atom_common_table_header *header;
  1086. struct atom_data_revision revision;
  1087. if (info && DATA_TABLES(firmwareinfo)) {
  1088. header = GET_IMAGE(struct atom_common_table_header,
  1089. DATA_TABLES(firmwareinfo));
  1090. get_atom_data_table_revision(header, &revision);
  1091. switch (revision.major) {
  1092. case 3:
  1093. switch (revision.minor) {
  1094. case 1:
  1095. result = get_firmware_info_v3_1(bp, info);
  1096. break;
  1097. default:
  1098. break;
  1099. }
  1100. break;
  1101. default:
  1102. break;
  1103. }
  1104. }
  1105. return result;
  1106. }
  1107. static enum bp_result get_firmware_info_v3_1(
  1108. struct bios_parser *bp,
  1109. struct dc_firmware_info *info)
  1110. {
  1111. struct atom_firmware_info_v3_1 *firmware_info;
  1112. struct atom_display_controller_info_v4_1 *dce_info = NULL;
  1113. if (!info)
  1114. return BP_RESULT_BADINPUT;
  1115. firmware_info = GET_IMAGE(struct atom_firmware_info_v3_1,
  1116. DATA_TABLES(firmwareinfo));
  1117. dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1,
  1118. DATA_TABLES(dce_info));
  1119. if (!firmware_info || !dce_info)
  1120. return BP_RESULT_BADBIOSTABLE;
  1121. memset(info, 0, sizeof(*info));
  1122. /* Pixel clock pll information. */
  1123. /* We need to convert from 10KHz units into KHz units */
  1124. info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
  1125. info->default_engine_clk = firmware_info->bootup_sclk_in10khz * 10;
  1126. /* 27MHz for Vega10: */
  1127. info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10;
  1128. /* Hardcode frequency if BIOS gives no DCE Ref Clk */
  1129. if (info->pll_info.crystal_frequency == 0)
  1130. info->pll_info.crystal_frequency = 27000;
  1131. /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/
  1132. info->dp_phy_ref_clk = dce_info->dpphy_refclk_10khz * 10;
  1133. info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10;
  1134. /* Get GPU PLL VCO Clock */
  1135. if (bp->cmd_tbl.get_smu_clock_info != NULL) {
  1136. /* VBIOS gives in 10KHz */
  1137. info->smu_gpu_pll_output_freq =
  1138. bp->cmd_tbl.get_smu_clock_info(bp) * 10;
  1139. }
  1140. return BP_RESULT_OK;
  1141. }
  1142. static enum bp_result bios_parser_get_encoder_cap_info(
  1143. struct dc_bios *dcb,
  1144. struct graphics_object_id object_id,
  1145. struct bp_encoder_cap_info *info)
  1146. {
  1147. struct bios_parser *bp = BP_FROM_DCB(dcb);
  1148. struct atom_display_object_path_v2 *object;
  1149. struct atom_encoder_caps_record *record = NULL;
  1150. if (!info)
  1151. return BP_RESULT_BADINPUT;
  1152. object = get_bios_object(bp, object_id);
  1153. if (!object)
  1154. return BP_RESULT_BADINPUT;
  1155. record = get_encoder_cap_record(bp, object);
  1156. if (!record)
  1157. return BP_RESULT_NORECORD;
  1158. info->DP_HBR2_CAP = (record->encodercaps &
  1159. ATOM_ENCODER_CAP_RECORD_HBR2) ? 1 : 0;
  1160. info->DP_HBR2_EN = (record->encodercaps &
  1161. ATOM_ENCODER_CAP_RECORD_HBR2_EN) ? 1 : 0;
  1162. info->DP_HBR3_EN = (record->encodercaps &
  1163. ATOM_ENCODER_CAP_RECORD_HBR3_EN) ? 1 : 0;
  1164. info->HDMI_6GB_EN = (record->encodercaps &
  1165. ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN) ? 1 : 0;
  1166. return BP_RESULT_OK;
  1167. }
  1168. static struct atom_encoder_caps_record *get_encoder_cap_record(
  1169. struct bios_parser *bp,
  1170. struct atom_display_object_path_v2 *object)
  1171. {
  1172. struct atom_common_record_header *header;
  1173. uint32_t offset;
  1174. if (!object) {
  1175. BREAK_TO_DEBUGGER(); /* Invalid object */
  1176. return NULL;
  1177. }
  1178. offset = object->encoder_recordoffset + bp->object_info_tbl_offset;
  1179. for (;;) {
  1180. header = GET_IMAGE(struct atom_common_record_header, offset);
  1181. if (!header)
  1182. return NULL;
  1183. offset += header->record_size;
  1184. if (header->record_type == LAST_RECORD_TYPE ||
  1185. !header->record_size)
  1186. break;
  1187. if (header->record_type != ATOM_ENCODER_CAP_RECORD_TYPE)
  1188. continue;
  1189. if (sizeof(struct atom_encoder_caps_record) <=
  1190. header->record_size)
  1191. return (struct atom_encoder_caps_record *)header;
  1192. }
  1193. return NULL;
  1194. }
  1195. /*
  1196. * get_integrated_info_v11
  1197. *
  1198. * @brief
  1199. * Get V8 integrated BIOS information
  1200. *
  1201. * @param
  1202. * bios_parser *bp - [in]BIOS parser handler to get master data table
  1203. * integrated_info *info - [out] store and output integrated info
  1204. *
  1205. * @return
  1206. * enum bp_result - BP_RESULT_OK if information is available,
  1207. * BP_RESULT_BADBIOSTABLE otherwise.
  1208. */
  1209. static enum bp_result get_integrated_info_v11(
  1210. struct bios_parser *bp,
  1211. struct integrated_info *info)
  1212. {
  1213. struct atom_integrated_system_info_v1_11 *info_v11;
  1214. uint32_t i;
  1215. info_v11 = GET_IMAGE(struct atom_integrated_system_info_v1_11,
  1216. DATA_TABLES(integratedsysteminfo));
  1217. if (info_v11 == NULL)
  1218. return BP_RESULT_BADBIOSTABLE;
  1219. info->gpu_cap_info =
  1220. le32_to_cpu(info_v11->gpucapinfo);
  1221. /*
  1222. * system_config: Bit[0] = 0 : PCIE power gating disabled
  1223. * = 1 : PCIE power gating enabled
  1224. * Bit[1] = 0 : DDR-PLL shut down disabled
  1225. * = 1 : DDR-PLL shut down enabled
  1226. * Bit[2] = 0 : DDR-PLL power down disabled
  1227. * = 1 : DDR-PLL power down enabled
  1228. */
  1229. info->system_config = le32_to_cpu(info_v11->system_config);
  1230. info->cpu_cap_info = le32_to_cpu(info_v11->cpucapinfo);
  1231. info->memory_type = info_v11->memorytype;
  1232. info->ma_channel_number = info_v11->umachannelnumber;
  1233. info->lvds_ss_percentage =
  1234. le16_to_cpu(info_v11->lvds_ss_percentage);
  1235. info->lvds_sspread_rate_in_10hz =
  1236. le16_to_cpu(info_v11->lvds_ss_rate_10hz);
  1237. info->hdmi_ss_percentage =
  1238. le16_to_cpu(info_v11->hdmi_ss_percentage);
  1239. info->hdmi_sspread_rate_in_10hz =
  1240. le16_to_cpu(info_v11->hdmi_ss_rate_10hz);
  1241. info->dvi_ss_percentage =
  1242. le16_to_cpu(info_v11->dvi_ss_percentage);
  1243. info->dvi_sspread_rate_in_10_hz =
  1244. le16_to_cpu(info_v11->dvi_ss_rate_10hz);
  1245. info->lvds_misc = info_v11->lvds_misc;
  1246. for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) {
  1247. info->ext_disp_conn_info.gu_id[i] =
  1248. info_v11->extdispconninfo.guid[i];
  1249. }
  1250. for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) {
  1251. info->ext_disp_conn_info.path[i].device_connector_id =
  1252. object_id_from_bios_object_id(
  1253. le16_to_cpu(info_v11->extdispconninfo.path[i].connectorobjid));
  1254. info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
  1255. object_id_from_bios_object_id(
  1256. le16_to_cpu(
  1257. info_v11->extdispconninfo.path[i].ext_encoder_objid));
  1258. info->ext_disp_conn_info.path[i].device_tag =
  1259. le16_to_cpu(
  1260. info_v11->extdispconninfo.path[i].device_tag);
  1261. info->ext_disp_conn_info.path[i].device_acpi_enum =
  1262. le16_to_cpu(
  1263. info_v11->extdispconninfo.path[i].device_acpi_enum);
  1264. info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index =
  1265. info_v11->extdispconninfo.path[i].auxddclut_index;
  1266. info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index =
  1267. info_v11->extdispconninfo.path[i].hpdlut_index;
  1268. info->ext_disp_conn_info.path[i].channel_mapping.raw =
  1269. info_v11->extdispconninfo.path[i].channelmapping;
  1270. info->ext_disp_conn_info.path[i].caps =
  1271. le16_to_cpu(info_v11->extdispconninfo.path[i].caps);
  1272. }
  1273. info->ext_disp_conn_info.checksum =
  1274. info_v11->extdispconninfo.checksum;
  1275. info->dp0_ext_hdmi_slv_addr = info_v11->dp0_retimer_set.HdmiSlvAddr;
  1276. info->dp0_ext_hdmi_reg_num = info_v11->dp0_retimer_set.HdmiRegNum;
  1277. for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) {
  1278. info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index =
  1279. info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
  1280. info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val =
  1281. info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
  1282. }
  1283. info->dp0_ext_hdmi_6g_reg_num = info_v11->dp0_retimer_set.Hdmi6GRegNum;
  1284. for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) {
  1285. info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
  1286. info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
  1287. info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
  1288. info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
  1289. }
  1290. info->dp1_ext_hdmi_slv_addr = info_v11->dp1_retimer_set.HdmiSlvAddr;
  1291. info->dp1_ext_hdmi_reg_num = info_v11->dp1_retimer_set.HdmiRegNum;
  1292. for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) {
  1293. info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index =
  1294. info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
  1295. info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val =
  1296. info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
  1297. }
  1298. info->dp1_ext_hdmi_6g_reg_num = info_v11->dp1_retimer_set.Hdmi6GRegNum;
  1299. for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) {
  1300. info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
  1301. info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
  1302. info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
  1303. info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
  1304. }
  1305. info->dp2_ext_hdmi_slv_addr = info_v11->dp2_retimer_set.HdmiSlvAddr;
  1306. info->dp2_ext_hdmi_reg_num = info_v11->dp2_retimer_set.HdmiRegNum;
  1307. for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) {
  1308. info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index =
  1309. info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
  1310. info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val =
  1311. info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
  1312. }
  1313. info->dp2_ext_hdmi_6g_reg_num = info_v11->dp2_retimer_set.Hdmi6GRegNum;
  1314. for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) {
  1315. info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
  1316. info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
  1317. info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
  1318. info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
  1319. }
  1320. info->dp3_ext_hdmi_slv_addr = info_v11->dp3_retimer_set.HdmiSlvAddr;
  1321. info->dp3_ext_hdmi_reg_num = info_v11->dp3_retimer_set.HdmiRegNum;
  1322. for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) {
  1323. info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index =
  1324. info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
  1325. info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val =
  1326. info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
  1327. }
  1328. info->dp3_ext_hdmi_6g_reg_num = info_v11->dp3_retimer_set.Hdmi6GRegNum;
  1329. for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) {
  1330. info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
  1331. info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
  1332. info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
  1333. info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
  1334. }
  1335. /** TODO - review **/
  1336. #if 0
  1337. info->boot_up_engine_clock = le32_to_cpu(info_v11->ulBootUpEngineClock)
  1338. * 10;
  1339. info->dentist_vco_freq = le32_to_cpu(info_v11->ulDentistVCOFreq) * 10;
  1340. info->boot_up_uma_clock = le32_to_cpu(info_v8->ulBootUpUMAClock) * 10;
  1341. for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
  1342. /* Convert [10KHz] into [KHz] */
  1343. info->disp_clk_voltage[i].max_supported_clk =
  1344. le32_to_cpu(info_v11->sDISPCLK_Voltage[i].
  1345. ulMaximumSupportedCLK) * 10;
  1346. info->disp_clk_voltage[i].voltage_index =
  1347. le32_to_cpu(info_v11->sDISPCLK_Voltage[i].ulVoltageIndex);
  1348. }
  1349. info->boot_up_req_display_vector =
  1350. le32_to_cpu(info_v11->ulBootUpReqDisplayVector);
  1351. info->boot_up_nb_voltage =
  1352. le16_to_cpu(info_v11->usBootUpNBVoltage);
  1353. info->ext_disp_conn_info_offset =
  1354. le16_to_cpu(info_v11->usExtDispConnInfoOffset);
  1355. info->gmc_restore_reset_time =
  1356. le32_to_cpu(info_v11->ulGMCRestoreResetTime);
  1357. info->minimum_n_clk =
  1358. le32_to_cpu(info_v11->ulNbpStateNClkFreq[0]);
  1359. for (i = 1; i < 4; ++i)
  1360. info->minimum_n_clk =
  1361. info->minimum_n_clk <
  1362. le32_to_cpu(info_v11->ulNbpStateNClkFreq[i]) ?
  1363. info->minimum_n_clk : le32_to_cpu(
  1364. info_v11->ulNbpStateNClkFreq[i]);
  1365. info->idle_n_clk = le32_to_cpu(info_v11->ulIdleNClk);
  1366. info->ddr_dll_power_up_time =
  1367. le32_to_cpu(info_v11->ulDDR_DLL_PowerUpTime);
  1368. info->ddr_pll_power_up_time =
  1369. le32_to_cpu(info_v11->ulDDR_PLL_PowerUpTime);
  1370. info->pcie_clk_ss_type = le16_to_cpu(info_v11->usPCIEClkSSType);
  1371. info->max_lvds_pclk_freq_in_single_link =
  1372. le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink);
  1373. info->max_lvds_pclk_freq_in_single_link =
  1374. le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink);
  1375. info->lvds_pwr_on_seq_dig_on_to_de_in_4ms =
  1376. info_v11->ucLVDSPwrOnSeqDIGONtoDE_in4Ms;
  1377. info->lvds_pwr_on_seq_de_to_vary_bl_in_4ms =
  1378. info_v11->ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms;
  1379. info->lvds_pwr_on_seq_vary_bl_to_blon_in_4ms =
  1380. info_v11->ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms;
  1381. info->lvds_pwr_off_seq_vary_bl_to_de_in4ms =
  1382. info_v11->ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms;
  1383. info->lvds_pwr_off_seq_de_to_dig_on_in4ms =
  1384. info_v11->ucLVDSPwrOffSeqDEtoDIGON_in4Ms;
  1385. info->lvds_pwr_off_seq_blon_to_vary_bl_in_4ms =
  1386. info_v11->ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms;
  1387. info->lvds_off_to_on_delay_in_4ms =
  1388. info_v11->ucLVDSOffToOnDelay_in4Ms;
  1389. info->lvds_bit_depth_control_val =
  1390. le32_to_cpu(info_v11->ulLCDBitDepthControlVal);
  1391. for (i = 0; i < NUMBER_OF_AVAILABLE_SCLK; ++i) {
  1392. /* Convert [10KHz] into [KHz] */
  1393. info->avail_s_clk[i].supported_s_clk =
  1394. le32_to_cpu(info_v11->sAvail_SCLK[i].ulSupportedSCLK)
  1395. * 10;
  1396. info->avail_s_clk[i].voltage_index =
  1397. le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageIndex);
  1398. info->avail_s_clk[i].voltage_id =
  1399. le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageID);
  1400. }
  1401. #endif /* TODO*/
  1402. return BP_RESULT_OK;
  1403. }
  1404. /*
  1405. * construct_integrated_info
  1406. *
  1407. * @brief
  1408. * Get integrated BIOS information based on table revision
  1409. *
  1410. * @param
  1411. * bios_parser *bp - [in]BIOS parser handler to get master data table
  1412. * integrated_info *info - [out] store and output integrated info
  1413. *
  1414. * @return
  1415. * enum bp_result - BP_RESULT_OK if information is available,
  1416. * BP_RESULT_BADBIOSTABLE otherwise.
  1417. */
  1418. static enum bp_result construct_integrated_info(
  1419. struct bios_parser *bp,
  1420. struct integrated_info *info)
  1421. {
  1422. enum bp_result result = BP_RESULT_BADBIOSTABLE;
  1423. struct atom_common_table_header *header;
  1424. struct atom_data_revision revision;
  1425. struct clock_voltage_caps temp = {0, 0};
  1426. uint32_t i;
  1427. uint32_t j;
  1428. if (info && DATA_TABLES(integratedsysteminfo)) {
  1429. header = GET_IMAGE(struct atom_common_table_header,
  1430. DATA_TABLES(integratedsysteminfo));
  1431. get_atom_data_table_revision(header, &revision);
  1432. /* Don't need to check major revision as they are all 1 */
  1433. switch (revision.minor) {
  1434. case 11:
  1435. result = get_integrated_info_v11(bp, info);
  1436. break;
  1437. default:
  1438. return result;
  1439. }
  1440. }
  1441. if (result != BP_RESULT_OK)
  1442. return result;
  1443. /* Sort voltage table from low to high*/
  1444. for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
  1445. for (j = i; j > 0; --j) {
  1446. if (info->disp_clk_voltage[j].max_supported_clk <
  1447. info->disp_clk_voltage[j-1].max_supported_clk
  1448. ) {
  1449. /* swap j and j - 1*/
  1450. temp = info->disp_clk_voltage[j-1];
  1451. info->disp_clk_voltage[j-1] =
  1452. info->disp_clk_voltage[j];
  1453. info->disp_clk_voltage[j] = temp;
  1454. }
  1455. }
  1456. }
  1457. return result;
  1458. }
  1459. static struct integrated_info *bios_parser_create_integrated_info(
  1460. struct dc_bios *dcb)
  1461. {
  1462. struct bios_parser *bp = BP_FROM_DCB(dcb);
  1463. struct integrated_info *info = NULL;
  1464. info = kzalloc(sizeof(struct integrated_info), GFP_KERNEL);
  1465. if (info == NULL) {
  1466. ASSERT_CRITICAL(0);
  1467. return NULL;
  1468. }
  1469. if (construct_integrated_info(bp, info) == BP_RESULT_OK)
  1470. return info;
  1471. kfree(info);
  1472. return NULL;
  1473. }
  1474. static const struct dc_vbios_funcs vbios_funcs = {
  1475. .get_connectors_number = bios_parser_get_connectors_number,
  1476. .get_encoder_id = bios_parser_get_encoder_id,
  1477. .get_connector_id = bios_parser_get_connector_id,
  1478. .get_dst_number = bios_parser_get_dst_number,
  1479. .get_src_obj = bios_parser_get_src_obj,
  1480. .get_dst_obj = bios_parser_get_dst_obj,
  1481. .get_i2c_info = bios_parser_get_i2c_info,
  1482. .get_voltage_ddc_info = bios_parser_get_voltage_ddc_info,
  1483. .get_thermal_ddc_info = bios_parser_get_thermal_ddc_info,
  1484. .get_hpd_info = bios_parser_get_hpd_info,
  1485. .get_device_tag = bios_parser_get_device_tag,
  1486. .get_firmware_info = bios_parser_get_firmware_info,
  1487. .get_spread_spectrum_info = bios_parser_get_spread_spectrum_info,
  1488. .get_ss_entry_number = bios_parser_get_ss_entry_number,
  1489. .get_embedded_panel_info = bios_parser_get_embedded_panel_info,
  1490. .get_gpio_pin_info = bios_parser_get_gpio_pin_info,
  1491. .get_encoder_cap_info = bios_parser_get_encoder_cap_info,
  1492. .is_device_id_supported = bios_parser_is_device_id_supported,
  1493. .is_accelerated_mode = bios_parser_is_accelerated_mode,
  1494. .set_scratch_critical_state = bios_parser_set_scratch_critical_state,
  1495. /* COMMANDS */
  1496. .encoder_control = bios_parser_encoder_control,
  1497. .transmitter_control = bios_parser_transmitter_control,
  1498. .enable_crtc = bios_parser_enable_crtc,
  1499. .set_pixel_clock = bios_parser_set_pixel_clock,
  1500. .set_dce_clock = bios_parser_set_dce_clock,
  1501. .program_crtc_timing = bios_parser_program_crtc_timing,
  1502. /* .blank_crtc = bios_parser_blank_crtc, */
  1503. .crtc_source_select = bios_parser_crtc_source_select,
  1504. /* .external_encoder_control = bios_parser_external_encoder_control, */
  1505. .enable_disp_power_gating = bios_parser_enable_disp_power_gating,
  1506. .post_init = bios_parser_post_init,
  1507. .bios_parser_destroy = firmware_parser_destroy,
  1508. .get_smu_clock_info = bios_parser_get_smu_clock_info,
  1509. };
  1510. static bool bios_parser_construct(
  1511. struct bios_parser *bp,
  1512. struct bp_init_data *init,
  1513. enum dce_version dce_version)
  1514. {
  1515. uint16_t *rom_header_offset = NULL;
  1516. struct atom_rom_header_v2_2 *rom_header = NULL;
  1517. struct display_object_info_table_v1_4 *object_info_tbl;
  1518. struct atom_data_revision tbl_rev = {0};
  1519. if (!init)
  1520. return false;
  1521. if (!init->bios)
  1522. return false;
  1523. bp->base.funcs = &vbios_funcs;
  1524. bp->base.bios = init->bios;
  1525. bp->base.bios_size = bp->base.bios[OFFSET_TO_ATOM_ROM_IMAGE_SIZE] * BIOS_IMAGE_SIZE_UNIT;
  1526. bp->base.ctx = init->ctx;
  1527. bp->base.bios_local_image = NULL;
  1528. rom_header_offset =
  1529. GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER);
  1530. if (!rom_header_offset)
  1531. return false;
  1532. rom_header = GET_IMAGE(struct atom_rom_header_v2_2, *rom_header_offset);
  1533. if (!rom_header)
  1534. return false;
  1535. get_atom_data_table_revision(&rom_header->table_header, &tbl_rev);
  1536. if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 2))
  1537. return false;
  1538. bp->master_data_tbl =
  1539. GET_IMAGE(struct atom_master_data_table_v2_1,
  1540. rom_header->masterdatatable_offset);
  1541. if (!bp->master_data_tbl)
  1542. return false;
  1543. bp->object_info_tbl_offset = DATA_TABLES(displayobjectinfo);
  1544. if (!bp->object_info_tbl_offset)
  1545. return false;
  1546. object_info_tbl =
  1547. GET_IMAGE(struct display_object_info_table_v1_4,
  1548. bp->object_info_tbl_offset);
  1549. if (!object_info_tbl)
  1550. return false;
  1551. get_atom_data_table_revision(&object_info_tbl->table_header,
  1552. &bp->object_info_tbl.revision);
  1553. if (bp->object_info_tbl.revision.major == 1
  1554. && bp->object_info_tbl.revision.minor >= 4) {
  1555. struct display_object_info_table_v1_4 *tbl_v1_4;
  1556. tbl_v1_4 = GET_IMAGE(struct display_object_info_table_v1_4,
  1557. bp->object_info_tbl_offset);
  1558. if (!tbl_v1_4)
  1559. return false;
  1560. bp->object_info_tbl.v1_4 = tbl_v1_4;
  1561. } else
  1562. return false;
  1563. dal_firmware_parser_init_cmd_tbl(bp);
  1564. dal_bios_parser_init_cmd_tbl_helper2(&bp->cmd_helper, dce_version);
  1565. bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base);
  1566. return true;
  1567. }
  1568. struct dc_bios *firmware_parser_create(
  1569. struct bp_init_data *init,
  1570. enum dce_version dce_version)
  1571. {
  1572. struct bios_parser *bp = NULL;
  1573. bp = kzalloc(sizeof(struct bios_parser), GFP_KERNEL);
  1574. if (!bp)
  1575. return NULL;
  1576. if (bios_parser_construct(bp, init, dce_version))
  1577. return &bp->base;
  1578. kfree(bp);
  1579. return NULL;
  1580. }