bios_parser2.c 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941
  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. static uint32_t bios_parser_get_vga_enabled_displays(
  1065. struct dc_bios *bios)
  1066. {
  1067. return bios_get_vga_enabled_displays(bios);
  1068. }
  1069. /**
  1070. * bios_parser_set_scratch_critical_state
  1071. *
  1072. * @brief
  1073. * update critical state bit in VBIOS scratch register
  1074. *
  1075. * @param
  1076. * bool - to set or reset state
  1077. */
  1078. static void bios_parser_set_scratch_critical_state(
  1079. struct dc_bios *dcb,
  1080. bool state)
  1081. {
  1082. bios_set_scratch_critical_state(dcb, state);
  1083. }
  1084. static enum bp_result bios_parser_get_firmware_info(
  1085. struct dc_bios *dcb,
  1086. struct dc_firmware_info *info)
  1087. {
  1088. struct bios_parser *bp = BP_FROM_DCB(dcb);
  1089. enum bp_result result = BP_RESULT_BADBIOSTABLE;
  1090. struct atom_common_table_header *header;
  1091. struct atom_data_revision revision;
  1092. if (info && DATA_TABLES(firmwareinfo)) {
  1093. header = GET_IMAGE(struct atom_common_table_header,
  1094. DATA_TABLES(firmwareinfo));
  1095. get_atom_data_table_revision(header, &revision);
  1096. switch (revision.major) {
  1097. case 3:
  1098. switch (revision.minor) {
  1099. case 1:
  1100. result = get_firmware_info_v3_1(bp, info);
  1101. break;
  1102. default:
  1103. break;
  1104. }
  1105. break;
  1106. default:
  1107. break;
  1108. }
  1109. }
  1110. return result;
  1111. }
  1112. static enum bp_result get_firmware_info_v3_1(
  1113. struct bios_parser *bp,
  1114. struct dc_firmware_info *info)
  1115. {
  1116. struct atom_firmware_info_v3_1 *firmware_info;
  1117. struct atom_display_controller_info_v4_1 *dce_info = NULL;
  1118. if (!info)
  1119. return BP_RESULT_BADINPUT;
  1120. firmware_info = GET_IMAGE(struct atom_firmware_info_v3_1,
  1121. DATA_TABLES(firmwareinfo));
  1122. dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1,
  1123. DATA_TABLES(dce_info));
  1124. if (!firmware_info || !dce_info)
  1125. return BP_RESULT_BADBIOSTABLE;
  1126. memset(info, 0, sizeof(*info));
  1127. /* Pixel clock pll information. */
  1128. /* We need to convert from 10KHz units into KHz units */
  1129. info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10;
  1130. info->default_engine_clk = firmware_info->bootup_sclk_in10khz * 10;
  1131. /* 27MHz for Vega10: */
  1132. info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10;
  1133. /* Hardcode frequency if BIOS gives no DCE Ref Clk */
  1134. if (info->pll_info.crystal_frequency == 0)
  1135. info->pll_info.crystal_frequency = 27000;
  1136. /*dp_phy_ref_clk is not correct for atom_display_controller_info_v4_2, but we don't use it*/
  1137. info->dp_phy_ref_clk = dce_info->dpphy_refclk_10khz * 10;
  1138. info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10;
  1139. /* Get GPU PLL VCO Clock */
  1140. if (bp->cmd_tbl.get_smu_clock_info != NULL) {
  1141. /* VBIOS gives in 10KHz */
  1142. info->smu_gpu_pll_output_freq =
  1143. bp->cmd_tbl.get_smu_clock_info(bp) * 10;
  1144. }
  1145. return BP_RESULT_OK;
  1146. }
  1147. static enum bp_result bios_parser_get_encoder_cap_info(
  1148. struct dc_bios *dcb,
  1149. struct graphics_object_id object_id,
  1150. struct bp_encoder_cap_info *info)
  1151. {
  1152. struct bios_parser *bp = BP_FROM_DCB(dcb);
  1153. struct atom_display_object_path_v2 *object;
  1154. struct atom_encoder_caps_record *record = NULL;
  1155. if (!info)
  1156. return BP_RESULT_BADINPUT;
  1157. object = get_bios_object(bp, object_id);
  1158. if (!object)
  1159. return BP_RESULT_BADINPUT;
  1160. record = get_encoder_cap_record(bp, object);
  1161. if (!record)
  1162. return BP_RESULT_NORECORD;
  1163. info->DP_HBR2_CAP = (record->encodercaps &
  1164. ATOM_ENCODER_CAP_RECORD_HBR2) ? 1 : 0;
  1165. info->DP_HBR2_EN = (record->encodercaps &
  1166. ATOM_ENCODER_CAP_RECORD_HBR2_EN) ? 1 : 0;
  1167. info->DP_HBR3_EN = (record->encodercaps &
  1168. ATOM_ENCODER_CAP_RECORD_HBR3_EN) ? 1 : 0;
  1169. info->HDMI_6GB_EN = (record->encodercaps &
  1170. ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN) ? 1 : 0;
  1171. return BP_RESULT_OK;
  1172. }
  1173. static struct atom_encoder_caps_record *get_encoder_cap_record(
  1174. struct bios_parser *bp,
  1175. struct atom_display_object_path_v2 *object)
  1176. {
  1177. struct atom_common_record_header *header;
  1178. uint32_t offset;
  1179. if (!object) {
  1180. BREAK_TO_DEBUGGER(); /* Invalid object */
  1181. return NULL;
  1182. }
  1183. offset = object->encoder_recordoffset + bp->object_info_tbl_offset;
  1184. for (;;) {
  1185. header = GET_IMAGE(struct atom_common_record_header, offset);
  1186. if (!header)
  1187. return NULL;
  1188. offset += header->record_size;
  1189. if (header->record_type == LAST_RECORD_TYPE ||
  1190. !header->record_size)
  1191. break;
  1192. if (header->record_type != ATOM_ENCODER_CAP_RECORD_TYPE)
  1193. continue;
  1194. if (sizeof(struct atom_encoder_caps_record) <=
  1195. header->record_size)
  1196. return (struct atom_encoder_caps_record *)header;
  1197. }
  1198. return NULL;
  1199. }
  1200. /*
  1201. * get_integrated_info_v11
  1202. *
  1203. * @brief
  1204. * Get V8 integrated BIOS information
  1205. *
  1206. * @param
  1207. * bios_parser *bp - [in]BIOS parser handler to get master data table
  1208. * integrated_info *info - [out] store and output integrated info
  1209. *
  1210. * @return
  1211. * enum bp_result - BP_RESULT_OK if information is available,
  1212. * BP_RESULT_BADBIOSTABLE otherwise.
  1213. */
  1214. static enum bp_result get_integrated_info_v11(
  1215. struct bios_parser *bp,
  1216. struct integrated_info *info)
  1217. {
  1218. struct atom_integrated_system_info_v1_11 *info_v11;
  1219. uint32_t i;
  1220. info_v11 = GET_IMAGE(struct atom_integrated_system_info_v1_11,
  1221. DATA_TABLES(integratedsysteminfo));
  1222. if (info_v11 == NULL)
  1223. return BP_RESULT_BADBIOSTABLE;
  1224. info->gpu_cap_info =
  1225. le32_to_cpu(info_v11->gpucapinfo);
  1226. /*
  1227. * system_config: Bit[0] = 0 : PCIE power gating disabled
  1228. * = 1 : PCIE power gating enabled
  1229. * Bit[1] = 0 : DDR-PLL shut down disabled
  1230. * = 1 : DDR-PLL shut down enabled
  1231. * Bit[2] = 0 : DDR-PLL power down disabled
  1232. * = 1 : DDR-PLL power down enabled
  1233. */
  1234. info->system_config = le32_to_cpu(info_v11->system_config);
  1235. info->cpu_cap_info = le32_to_cpu(info_v11->cpucapinfo);
  1236. info->memory_type = info_v11->memorytype;
  1237. info->ma_channel_number = info_v11->umachannelnumber;
  1238. info->lvds_ss_percentage =
  1239. le16_to_cpu(info_v11->lvds_ss_percentage);
  1240. info->lvds_sspread_rate_in_10hz =
  1241. le16_to_cpu(info_v11->lvds_ss_rate_10hz);
  1242. info->hdmi_ss_percentage =
  1243. le16_to_cpu(info_v11->hdmi_ss_percentage);
  1244. info->hdmi_sspread_rate_in_10hz =
  1245. le16_to_cpu(info_v11->hdmi_ss_rate_10hz);
  1246. info->dvi_ss_percentage =
  1247. le16_to_cpu(info_v11->dvi_ss_percentage);
  1248. info->dvi_sspread_rate_in_10_hz =
  1249. le16_to_cpu(info_v11->dvi_ss_rate_10hz);
  1250. info->lvds_misc = info_v11->lvds_misc;
  1251. for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) {
  1252. info->ext_disp_conn_info.gu_id[i] =
  1253. info_v11->extdispconninfo.guid[i];
  1254. }
  1255. for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) {
  1256. info->ext_disp_conn_info.path[i].device_connector_id =
  1257. object_id_from_bios_object_id(
  1258. le16_to_cpu(info_v11->extdispconninfo.path[i].connectorobjid));
  1259. info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
  1260. object_id_from_bios_object_id(
  1261. le16_to_cpu(
  1262. info_v11->extdispconninfo.path[i].ext_encoder_objid));
  1263. info->ext_disp_conn_info.path[i].device_tag =
  1264. le16_to_cpu(
  1265. info_v11->extdispconninfo.path[i].device_tag);
  1266. info->ext_disp_conn_info.path[i].device_acpi_enum =
  1267. le16_to_cpu(
  1268. info_v11->extdispconninfo.path[i].device_acpi_enum);
  1269. info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index =
  1270. info_v11->extdispconninfo.path[i].auxddclut_index;
  1271. info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index =
  1272. info_v11->extdispconninfo.path[i].hpdlut_index;
  1273. info->ext_disp_conn_info.path[i].channel_mapping.raw =
  1274. info_v11->extdispconninfo.path[i].channelmapping;
  1275. info->ext_disp_conn_info.path[i].caps =
  1276. le16_to_cpu(info_v11->extdispconninfo.path[i].caps);
  1277. }
  1278. info->ext_disp_conn_info.checksum =
  1279. info_v11->extdispconninfo.checksum;
  1280. info->dp0_ext_hdmi_slv_addr = info_v11->dp0_retimer_set.HdmiSlvAddr;
  1281. info->dp0_ext_hdmi_reg_num = info_v11->dp0_retimer_set.HdmiRegNum;
  1282. for (i = 0; i < info->dp0_ext_hdmi_reg_num; i++) {
  1283. info->dp0_ext_hdmi_reg_settings[i].i2c_reg_index =
  1284. info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
  1285. info->dp0_ext_hdmi_reg_settings[i].i2c_reg_val =
  1286. info_v11->dp0_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
  1287. }
  1288. info->dp0_ext_hdmi_6g_reg_num = info_v11->dp0_retimer_set.Hdmi6GRegNum;
  1289. for (i = 0; i < info->dp0_ext_hdmi_6g_reg_num; i++) {
  1290. info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
  1291. info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
  1292. info->dp0_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
  1293. info_v11->dp0_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
  1294. }
  1295. info->dp1_ext_hdmi_slv_addr = info_v11->dp1_retimer_set.HdmiSlvAddr;
  1296. info->dp1_ext_hdmi_reg_num = info_v11->dp1_retimer_set.HdmiRegNum;
  1297. for (i = 0; i < info->dp1_ext_hdmi_reg_num; i++) {
  1298. info->dp1_ext_hdmi_reg_settings[i].i2c_reg_index =
  1299. info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
  1300. info->dp1_ext_hdmi_reg_settings[i].i2c_reg_val =
  1301. info_v11->dp1_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
  1302. }
  1303. info->dp1_ext_hdmi_6g_reg_num = info_v11->dp1_retimer_set.Hdmi6GRegNum;
  1304. for (i = 0; i < info->dp1_ext_hdmi_6g_reg_num; i++) {
  1305. info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
  1306. info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
  1307. info->dp1_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
  1308. info_v11->dp1_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
  1309. }
  1310. info->dp2_ext_hdmi_slv_addr = info_v11->dp2_retimer_set.HdmiSlvAddr;
  1311. info->dp2_ext_hdmi_reg_num = info_v11->dp2_retimer_set.HdmiRegNum;
  1312. for (i = 0; i < info->dp2_ext_hdmi_reg_num; i++) {
  1313. info->dp2_ext_hdmi_reg_settings[i].i2c_reg_index =
  1314. info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
  1315. info->dp2_ext_hdmi_reg_settings[i].i2c_reg_val =
  1316. info_v11->dp2_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
  1317. }
  1318. info->dp2_ext_hdmi_6g_reg_num = info_v11->dp2_retimer_set.Hdmi6GRegNum;
  1319. for (i = 0; i < info->dp2_ext_hdmi_6g_reg_num; i++) {
  1320. info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
  1321. info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
  1322. info->dp2_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
  1323. info_v11->dp2_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
  1324. }
  1325. info->dp3_ext_hdmi_slv_addr = info_v11->dp3_retimer_set.HdmiSlvAddr;
  1326. info->dp3_ext_hdmi_reg_num = info_v11->dp3_retimer_set.HdmiRegNum;
  1327. for (i = 0; i < info->dp3_ext_hdmi_reg_num; i++) {
  1328. info->dp3_ext_hdmi_reg_settings[i].i2c_reg_index =
  1329. info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegIndex;
  1330. info->dp3_ext_hdmi_reg_settings[i].i2c_reg_val =
  1331. info_v11->dp3_retimer_set.HdmiRegSetting[i].ucI2cRegVal;
  1332. }
  1333. info->dp3_ext_hdmi_6g_reg_num = info_v11->dp3_retimer_set.Hdmi6GRegNum;
  1334. for (i = 0; i < info->dp3_ext_hdmi_6g_reg_num; i++) {
  1335. info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_index =
  1336. info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegIndex;
  1337. info->dp3_ext_hdmi_6g_reg_settings[i].i2c_reg_val =
  1338. info_v11->dp3_retimer_set.Hdmi6GhzRegSetting[i].ucI2cRegVal;
  1339. }
  1340. /** TODO - review **/
  1341. #if 0
  1342. info->boot_up_engine_clock = le32_to_cpu(info_v11->ulBootUpEngineClock)
  1343. * 10;
  1344. info->dentist_vco_freq = le32_to_cpu(info_v11->ulDentistVCOFreq) * 10;
  1345. info->boot_up_uma_clock = le32_to_cpu(info_v8->ulBootUpUMAClock) * 10;
  1346. for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
  1347. /* Convert [10KHz] into [KHz] */
  1348. info->disp_clk_voltage[i].max_supported_clk =
  1349. le32_to_cpu(info_v11->sDISPCLK_Voltage[i].
  1350. ulMaximumSupportedCLK) * 10;
  1351. info->disp_clk_voltage[i].voltage_index =
  1352. le32_to_cpu(info_v11->sDISPCLK_Voltage[i].ulVoltageIndex);
  1353. }
  1354. info->boot_up_req_display_vector =
  1355. le32_to_cpu(info_v11->ulBootUpReqDisplayVector);
  1356. info->boot_up_nb_voltage =
  1357. le16_to_cpu(info_v11->usBootUpNBVoltage);
  1358. info->ext_disp_conn_info_offset =
  1359. le16_to_cpu(info_v11->usExtDispConnInfoOffset);
  1360. info->gmc_restore_reset_time =
  1361. le32_to_cpu(info_v11->ulGMCRestoreResetTime);
  1362. info->minimum_n_clk =
  1363. le32_to_cpu(info_v11->ulNbpStateNClkFreq[0]);
  1364. for (i = 1; i < 4; ++i)
  1365. info->minimum_n_clk =
  1366. info->minimum_n_clk <
  1367. le32_to_cpu(info_v11->ulNbpStateNClkFreq[i]) ?
  1368. info->minimum_n_clk : le32_to_cpu(
  1369. info_v11->ulNbpStateNClkFreq[i]);
  1370. info->idle_n_clk = le32_to_cpu(info_v11->ulIdleNClk);
  1371. info->ddr_dll_power_up_time =
  1372. le32_to_cpu(info_v11->ulDDR_DLL_PowerUpTime);
  1373. info->ddr_pll_power_up_time =
  1374. le32_to_cpu(info_v11->ulDDR_PLL_PowerUpTime);
  1375. info->pcie_clk_ss_type = le16_to_cpu(info_v11->usPCIEClkSSType);
  1376. info->max_lvds_pclk_freq_in_single_link =
  1377. le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink);
  1378. info->max_lvds_pclk_freq_in_single_link =
  1379. le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink);
  1380. info->lvds_pwr_on_seq_dig_on_to_de_in_4ms =
  1381. info_v11->ucLVDSPwrOnSeqDIGONtoDE_in4Ms;
  1382. info->lvds_pwr_on_seq_de_to_vary_bl_in_4ms =
  1383. info_v11->ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms;
  1384. info->lvds_pwr_on_seq_vary_bl_to_blon_in_4ms =
  1385. info_v11->ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms;
  1386. info->lvds_pwr_off_seq_vary_bl_to_de_in4ms =
  1387. info_v11->ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms;
  1388. info->lvds_pwr_off_seq_de_to_dig_on_in4ms =
  1389. info_v11->ucLVDSPwrOffSeqDEtoDIGON_in4Ms;
  1390. info->lvds_pwr_off_seq_blon_to_vary_bl_in_4ms =
  1391. info_v11->ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms;
  1392. info->lvds_off_to_on_delay_in_4ms =
  1393. info_v11->ucLVDSOffToOnDelay_in4Ms;
  1394. info->lvds_bit_depth_control_val =
  1395. le32_to_cpu(info_v11->ulLCDBitDepthControlVal);
  1396. for (i = 0; i < NUMBER_OF_AVAILABLE_SCLK; ++i) {
  1397. /* Convert [10KHz] into [KHz] */
  1398. info->avail_s_clk[i].supported_s_clk =
  1399. le32_to_cpu(info_v11->sAvail_SCLK[i].ulSupportedSCLK)
  1400. * 10;
  1401. info->avail_s_clk[i].voltage_index =
  1402. le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageIndex);
  1403. info->avail_s_clk[i].voltage_id =
  1404. le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageID);
  1405. }
  1406. #endif /* TODO*/
  1407. return BP_RESULT_OK;
  1408. }
  1409. /*
  1410. * construct_integrated_info
  1411. *
  1412. * @brief
  1413. * Get integrated BIOS information based on table revision
  1414. *
  1415. * @param
  1416. * bios_parser *bp - [in]BIOS parser handler to get master data table
  1417. * integrated_info *info - [out] store and output integrated info
  1418. *
  1419. * @return
  1420. * enum bp_result - BP_RESULT_OK if information is available,
  1421. * BP_RESULT_BADBIOSTABLE otherwise.
  1422. */
  1423. static enum bp_result construct_integrated_info(
  1424. struct bios_parser *bp,
  1425. struct integrated_info *info)
  1426. {
  1427. enum bp_result result = BP_RESULT_BADBIOSTABLE;
  1428. struct atom_common_table_header *header;
  1429. struct atom_data_revision revision;
  1430. struct clock_voltage_caps temp = {0, 0};
  1431. uint32_t i;
  1432. uint32_t j;
  1433. if (info && DATA_TABLES(integratedsysteminfo)) {
  1434. header = GET_IMAGE(struct atom_common_table_header,
  1435. DATA_TABLES(integratedsysteminfo));
  1436. get_atom_data_table_revision(header, &revision);
  1437. /* Don't need to check major revision as they are all 1 */
  1438. switch (revision.minor) {
  1439. case 11:
  1440. result = get_integrated_info_v11(bp, info);
  1441. break;
  1442. default:
  1443. return result;
  1444. }
  1445. }
  1446. if (result != BP_RESULT_OK)
  1447. return result;
  1448. /* Sort voltage table from low to high*/
  1449. for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
  1450. for (j = i; j > 0; --j) {
  1451. if (info->disp_clk_voltage[j].max_supported_clk <
  1452. info->disp_clk_voltage[j-1].max_supported_clk
  1453. ) {
  1454. /* swap j and j - 1*/
  1455. temp = info->disp_clk_voltage[j-1];
  1456. info->disp_clk_voltage[j-1] =
  1457. info->disp_clk_voltage[j];
  1458. info->disp_clk_voltage[j] = temp;
  1459. }
  1460. }
  1461. }
  1462. return result;
  1463. }
  1464. static struct integrated_info *bios_parser_create_integrated_info(
  1465. struct dc_bios *dcb)
  1466. {
  1467. struct bios_parser *bp = BP_FROM_DCB(dcb);
  1468. struct integrated_info *info = NULL;
  1469. info = kzalloc(sizeof(struct integrated_info), GFP_KERNEL);
  1470. if (info == NULL) {
  1471. ASSERT_CRITICAL(0);
  1472. return NULL;
  1473. }
  1474. if (construct_integrated_info(bp, info) == BP_RESULT_OK)
  1475. return info;
  1476. kfree(info);
  1477. return NULL;
  1478. }
  1479. static const struct dc_vbios_funcs vbios_funcs = {
  1480. .get_connectors_number = bios_parser_get_connectors_number,
  1481. .get_encoder_id = bios_parser_get_encoder_id,
  1482. .get_connector_id = bios_parser_get_connector_id,
  1483. .get_dst_number = bios_parser_get_dst_number,
  1484. .get_src_obj = bios_parser_get_src_obj,
  1485. .get_dst_obj = bios_parser_get_dst_obj,
  1486. .get_i2c_info = bios_parser_get_i2c_info,
  1487. .get_voltage_ddc_info = bios_parser_get_voltage_ddc_info,
  1488. .get_thermal_ddc_info = bios_parser_get_thermal_ddc_info,
  1489. .get_hpd_info = bios_parser_get_hpd_info,
  1490. .get_device_tag = bios_parser_get_device_tag,
  1491. .get_firmware_info = bios_parser_get_firmware_info,
  1492. .get_spread_spectrum_info = bios_parser_get_spread_spectrum_info,
  1493. .get_ss_entry_number = bios_parser_get_ss_entry_number,
  1494. .get_embedded_panel_info = bios_parser_get_embedded_panel_info,
  1495. .get_gpio_pin_info = bios_parser_get_gpio_pin_info,
  1496. .get_encoder_cap_info = bios_parser_get_encoder_cap_info,
  1497. .is_device_id_supported = bios_parser_is_device_id_supported,
  1498. .is_accelerated_mode = bios_parser_is_accelerated_mode,
  1499. .get_vga_enabled_displays = bios_parser_get_vga_enabled_displays,
  1500. .set_scratch_critical_state = bios_parser_set_scratch_critical_state,
  1501. /* COMMANDS */
  1502. .encoder_control = bios_parser_encoder_control,
  1503. .transmitter_control = bios_parser_transmitter_control,
  1504. .enable_crtc = bios_parser_enable_crtc,
  1505. .set_pixel_clock = bios_parser_set_pixel_clock,
  1506. .set_dce_clock = bios_parser_set_dce_clock,
  1507. .program_crtc_timing = bios_parser_program_crtc_timing,
  1508. /* .blank_crtc = bios_parser_blank_crtc, */
  1509. .crtc_source_select = bios_parser_crtc_source_select,
  1510. /* .external_encoder_control = bios_parser_external_encoder_control, */
  1511. .enable_disp_power_gating = bios_parser_enable_disp_power_gating,
  1512. .post_init = bios_parser_post_init,
  1513. .bios_parser_destroy = firmware_parser_destroy,
  1514. .get_smu_clock_info = bios_parser_get_smu_clock_info,
  1515. };
  1516. static bool bios_parser_construct(
  1517. struct bios_parser *bp,
  1518. struct bp_init_data *init,
  1519. enum dce_version dce_version)
  1520. {
  1521. uint16_t *rom_header_offset = NULL;
  1522. struct atom_rom_header_v2_2 *rom_header = NULL;
  1523. struct display_object_info_table_v1_4 *object_info_tbl;
  1524. struct atom_data_revision tbl_rev = {0};
  1525. if (!init)
  1526. return false;
  1527. if (!init->bios)
  1528. return false;
  1529. bp->base.funcs = &vbios_funcs;
  1530. bp->base.bios = init->bios;
  1531. bp->base.bios_size = bp->base.bios[OFFSET_TO_ATOM_ROM_IMAGE_SIZE] * BIOS_IMAGE_SIZE_UNIT;
  1532. bp->base.ctx = init->ctx;
  1533. bp->base.bios_local_image = NULL;
  1534. rom_header_offset =
  1535. GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER);
  1536. if (!rom_header_offset)
  1537. return false;
  1538. rom_header = GET_IMAGE(struct atom_rom_header_v2_2, *rom_header_offset);
  1539. if (!rom_header)
  1540. return false;
  1541. get_atom_data_table_revision(&rom_header->table_header, &tbl_rev);
  1542. if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 2))
  1543. return false;
  1544. bp->master_data_tbl =
  1545. GET_IMAGE(struct atom_master_data_table_v2_1,
  1546. rom_header->masterdatatable_offset);
  1547. if (!bp->master_data_tbl)
  1548. return false;
  1549. bp->object_info_tbl_offset = DATA_TABLES(displayobjectinfo);
  1550. if (!bp->object_info_tbl_offset)
  1551. return false;
  1552. object_info_tbl =
  1553. GET_IMAGE(struct display_object_info_table_v1_4,
  1554. bp->object_info_tbl_offset);
  1555. if (!object_info_tbl)
  1556. return false;
  1557. get_atom_data_table_revision(&object_info_tbl->table_header,
  1558. &bp->object_info_tbl.revision);
  1559. if (bp->object_info_tbl.revision.major == 1
  1560. && bp->object_info_tbl.revision.minor >= 4) {
  1561. struct display_object_info_table_v1_4 *tbl_v1_4;
  1562. tbl_v1_4 = GET_IMAGE(struct display_object_info_table_v1_4,
  1563. bp->object_info_tbl_offset);
  1564. if (!tbl_v1_4)
  1565. return false;
  1566. bp->object_info_tbl.v1_4 = tbl_v1_4;
  1567. } else
  1568. return false;
  1569. dal_firmware_parser_init_cmd_tbl(bp);
  1570. dal_bios_parser_init_cmd_tbl_helper2(&bp->cmd_helper, dce_version);
  1571. bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base);
  1572. return true;
  1573. }
  1574. struct dc_bios *firmware_parser_create(
  1575. struct bp_init_data *init,
  1576. enum dce_version dce_version)
  1577. {
  1578. struct bios_parser *bp = NULL;
  1579. bp = kzalloc(sizeof(struct bios_parser), GFP_KERNEL);
  1580. if (!bp)
  1581. return NULL;
  1582. if (bios_parser_construct(bp, init, dce_version))
  1583. return &bp->base;
  1584. kfree(bp);
  1585. return NULL;
  1586. }