mdp5_cfg.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. /*
  2. * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 and
  6. * only version 2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include "mdp5_kms.h"
  14. #include "mdp5_cfg.h"
  15. struct mdp5_cfg_handler {
  16. int revision;
  17. struct mdp5_cfg config;
  18. };
  19. /* mdp5_cfg must be exposed (used in mdp5.xml.h) */
  20. const struct mdp5_cfg_hw *mdp5_cfg = NULL;
  21. const struct mdp5_cfg_hw msm8x74v1_config = {
  22. .name = "msm8x74v1",
  23. .mdp = {
  24. .count = 1,
  25. .caps = MDP_CAP_SMP |
  26. 0,
  27. },
  28. .smp = {
  29. .mmb_count = 22,
  30. .mmb_size = 4096,
  31. .clients = {
  32. [SSPP_VIG0] = 1, [SSPP_VIG1] = 4, [SSPP_VIG2] = 7,
  33. [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
  34. [SSPP_RGB0] = 16, [SSPP_RGB1] = 17, [SSPP_RGB2] = 18,
  35. },
  36. },
  37. .ctl = {
  38. .count = 5,
  39. .base = { 0x00500, 0x00600, 0x00700, 0x00800, 0x00900 },
  40. .flush_hw_mask = 0x0003ffff,
  41. },
  42. .pipe_vig = {
  43. .count = 3,
  44. .base = { 0x01100, 0x01500, 0x01900 },
  45. .caps = MDP_PIPE_CAP_HFLIP |
  46. MDP_PIPE_CAP_VFLIP |
  47. MDP_PIPE_CAP_SCALE |
  48. MDP_PIPE_CAP_CSC |
  49. 0,
  50. },
  51. .pipe_rgb = {
  52. .count = 3,
  53. .base = { 0x01d00, 0x02100, 0x02500 },
  54. .caps = MDP_PIPE_CAP_HFLIP |
  55. MDP_PIPE_CAP_VFLIP |
  56. MDP_PIPE_CAP_SCALE |
  57. 0,
  58. },
  59. .pipe_dma = {
  60. .count = 2,
  61. .base = { 0x02900, 0x02d00 },
  62. .caps = MDP_PIPE_CAP_HFLIP |
  63. MDP_PIPE_CAP_VFLIP |
  64. 0,
  65. },
  66. .lm = {
  67. .count = 5,
  68. .base = { 0x03100, 0x03500, 0x03900, 0x03d00, 0x04100 },
  69. .instances = {
  70. { .id = 0, .pp = 0, .dspp = 0,
  71. .caps = MDP_LM_CAP_DISPLAY, },
  72. { .id = 1, .pp = 1, .dspp = 1,
  73. .caps = MDP_LM_CAP_DISPLAY, },
  74. { .id = 2, .pp = 2, .dspp = 2,
  75. .caps = MDP_LM_CAP_DISPLAY, },
  76. { .id = 3, .pp = -1, .dspp = -1,
  77. .caps = MDP_LM_CAP_WB },
  78. { .id = 4, .pp = -1, .dspp = -1,
  79. .caps = MDP_LM_CAP_WB },
  80. },
  81. .nb_stages = 5,
  82. },
  83. .dspp = {
  84. .count = 3,
  85. .base = { 0x04500, 0x04900, 0x04d00 },
  86. },
  87. .pp = {
  88. .count = 3,
  89. .base = { 0x21a00, 0x21b00, 0x21c00 },
  90. },
  91. .intf = {
  92. .base = { 0x21000, 0x21200, 0x21400, 0x21600 },
  93. .connect = {
  94. [0] = INTF_eDP,
  95. [1] = INTF_DSI,
  96. [2] = INTF_DSI,
  97. [3] = INTF_HDMI,
  98. },
  99. },
  100. .max_clk = 200000000,
  101. };
  102. const struct mdp5_cfg_hw msm8x74v2_config = {
  103. .name = "msm8x74",
  104. .mdp = {
  105. .count = 1,
  106. .caps = MDP_CAP_SMP |
  107. 0,
  108. },
  109. .smp = {
  110. .mmb_count = 22,
  111. .mmb_size = 4096,
  112. .clients = {
  113. [SSPP_VIG0] = 1, [SSPP_VIG1] = 4, [SSPP_VIG2] = 7,
  114. [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
  115. [SSPP_RGB0] = 16, [SSPP_RGB1] = 17, [SSPP_RGB2] = 18,
  116. },
  117. },
  118. .ctl = {
  119. .count = 5,
  120. .base = { 0x00500, 0x00600, 0x00700, 0x00800, 0x00900 },
  121. .flush_hw_mask = 0x0003ffff,
  122. },
  123. .pipe_vig = {
  124. .count = 3,
  125. .base = { 0x01100, 0x01500, 0x01900 },
  126. .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
  127. MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
  128. MDP_PIPE_CAP_DECIMATION,
  129. },
  130. .pipe_rgb = {
  131. .count = 3,
  132. .base = { 0x01d00, 0x02100, 0x02500 },
  133. .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
  134. MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
  135. },
  136. .pipe_dma = {
  137. .count = 2,
  138. .base = { 0x02900, 0x02d00 },
  139. .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
  140. },
  141. .lm = {
  142. .count = 5,
  143. .base = { 0x03100, 0x03500, 0x03900, 0x03d00, 0x04100 },
  144. .instances = {
  145. { .id = 0, .pp = 0, .dspp = 0,
  146. .caps = MDP_LM_CAP_DISPLAY, },
  147. { .id = 1, .pp = 1, .dspp = 1,
  148. .caps = MDP_LM_CAP_DISPLAY, },
  149. { .id = 2, .pp = 2, .dspp = 2,
  150. .caps = MDP_LM_CAP_DISPLAY, },
  151. { .id = 3, .pp = -1, .dspp = -1,
  152. .caps = MDP_LM_CAP_WB, },
  153. { .id = 4, .pp = -1, .dspp = -1,
  154. .caps = MDP_LM_CAP_WB, },
  155. },
  156. .nb_stages = 5,
  157. .max_width = 2048,
  158. .max_height = 0xFFFF,
  159. },
  160. .dspp = {
  161. .count = 3,
  162. .base = { 0x04500, 0x04900, 0x04d00 },
  163. },
  164. .ad = {
  165. .count = 2,
  166. .base = { 0x13000, 0x13200 },
  167. },
  168. .pp = {
  169. .count = 3,
  170. .base = { 0x12c00, 0x12d00, 0x12e00 },
  171. },
  172. .intf = {
  173. .base = { 0x12400, 0x12600, 0x12800, 0x12a00 },
  174. .connect = {
  175. [0] = INTF_eDP,
  176. [1] = INTF_DSI,
  177. [2] = INTF_DSI,
  178. [3] = INTF_HDMI,
  179. },
  180. },
  181. .max_clk = 200000000,
  182. };
  183. const struct mdp5_cfg_hw apq8084_config = {
  184. .name = "apq8084",
  185. .mdp = {
  186. .count = 1,
  187. .caps = MDP_CAP_SMP |
  188. MDP_CAP_SRC_SPLIT |
  189. 0,
  190. },
  191. .smp = {
  192. .mmb_count = 44,
  193. .mmb_size = 8192,
  194. .clients = {
  195. [SSPP_VIG0] = 1, [SSPP_VIG1] = 4,
  196. [SSPP_VIG2] = 7, [SSPP_VIG3] = 19,
  197. [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
  198. [SSPP_RGB0] = 16, [SSPP_RGB1] = 17,
  199. [SSPP_RGB2] = 18, [SSPP_RGB3] = 22,
  200. },
  201. .reserved_state[0] = GENMASK(7, 0), /* first 8 MMBs */
  202. .reserved = {
  203. /* Two SMP blocks are statically tied to RGB pipes: */
  204. [16] = 2, [17] = 2, [18] = 2, [22] = 2,
  205. },
  206. },
  207. .ctl = {
  208. .count = 5,
  209. .base = { 0x00500, 0x00600, 0x00700, 0x00800, 0x00900 },
  210. .flush_hw_mask = 0x003fffff,
  211. },
  212. .pipe_vig = {
  213. .count = 4,
  214. .base = { 0x01100, 0x01500, 0x01900, 0x01d00 },
  215. .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
  216. MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
  217. MDP_PIPE_CAP_DECIMATION,
  218. },
  219. .pipe_rgb = {
  220. .count = 4,
  221. .base = { 0x02100, 0x02500, 0x02900, 0x02d00 },
  222. .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
  223. MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
  224. },
  225. .pipe_dma = {
  226. .count = 2,
  227. .base = { 0x03100, 0x03500 },
  228. .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
  229. },
  230. .lm = {
  231. .count = 6,
  232. .base = { 0x03900, 0x03d00, 0x04100, 0x04500, 0x04900, 0x04d00 },
  233. .instances = {
  234. { .id = 0, .pp = 0, .dspp = 0,
  235. .caps = MDP_LM_CAP_DISPLAY |
  236. MDP_LM_CAP_PAIR, },
  237. { .id = 1, .pp = 1, .dspp = 1,
  238. .caps = MDP_LM_CAP_DISPLAY, },
  239. { .id = 2, .pp = 2, .dspp = 2,
  240. .caps = MDP_LM_CAP_DISPLAY |
  241. MDP_LM_CAP_PAIR, },
  242. { .id = 3, .pp = -1, .dspp = -1,
  243. .caps = MDP_LM_CAP_WB, },
  244. { .id = 4, .pp = -1, .dspp = -1,
  245. .caps = MDP_LM_CAP_WB, },
  246. { .id = 5, .pp = 3, .dspp = 3,
  247. .caps = MDP_LM_CAP_DISPLAY, },
  248. },
  249. .nb_stages = 5,
  250. .max_width = 2048,
  251. .max_height = 0xFFFF,
  252. },
  253. .dspp = {
  254. .count = 4,
  255. .base = { 0x05100, 0x05500, 0x05900, 0x05d00 },
  256. },
  257. .ad = {
  258. .count = 3,
  259. .base = { 0x13400, 0x13600, 0x13800 },
  260. },
  261. .pp = {
  262. .count = 4,
  263. .base = { 0x12e00, 0x12f00, 0x13000, 0x13100 },
  264. },
  265. .intf = {
  266. .base = { 0x12400, 0x12600, 0x12800, 0x12a00, 0x12c00 },
  267. .connect = {
  268. [0] = INTF_eDP,
  269. [1] = INTF_DSI,
  270. [2] = INTF_DSI,
  271. [3] = INTF_HDMI,
  272. },
  273. },
  274. .max_clk = 320000000,
  275. };
  276. const struct mdp5_cfg_hw msm8x16_config = {
  277. .name = "msm8x16",
  278. .mdp = {
  279. .count = 1,
  280. .base = { 0x0 },
  281. .caps = MDP_CAP_SMP |
  282. 0,
  283. },
  284. .smp = {
  285. .mmb_count = 8,
  286. .mmb_size = 8192,
  287. .clients = {
  288. [SSPP_VIG0] = 1, [SSPP_DMA0] = 4,
  289. [SSPP_RGB0] = 7, [SSPP_RGB1] = 8,
  290. },
  291. },
  292. .ctl = {
  293. .count = 5,
  294. .base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
  295. .flush_hw_mask = 0x4003ffff,
  296. },
  297. .pipe_vig = {
  298. .count = 1,
  299. .base = { 0x04000 },
  300. .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
  301. MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
  302. MDP_PIPE_CAP_DECIMATION,
  303. },
  304. .pipe_rgb = {
  305. .count = 2,
  306. .base = { 0x14000, 0x16000 },
  307. .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
  308. MDP_PIPE_CAP_DECIMATION,
  309. },
  310. .pipe_dma = {
  311. .count = 1,
  312. .base = { 0x24000 },
  313. .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
  314. },
  315. .lm = {
  316. .count = 2, /* LM0 and LM3 */
  317. .base = { 0x44000, 0x47000 },
  318. .instances = {
  319. { .id = 0, .pp = 0, .dspp = 0,
  320. .caps = MDP_LM_CAP_DISPLAY, },
  321. { .id = 3, .pp = -1, .dspp = -1,
  322. .caps = MDP_LM_CAP_WB },
  323. },
  324. .nb_stages = 8,
  325. .max_width = 2048,
  326. .max_height = 0xFFFF,
  327. },
  328. .dspp = {
  329. .count = 1,
  330. .base = { 0x54000 },
  331. },
  332. .intf = {
  333. .base = { 0x00000, 0x6a800 },
  334. .connect = {
  335. [0] = INTF_DISABLED,
  336. [1] = INTF_DSI,
  337. },
  338. },
  339. .max_clk = 320000000,
  340. };
  341. const struct mdp5_cfg_hw msm8x94_config = {
  342. .name = "msm8x94",
  343. .mdp = {
  344. .count = 1,
  345. .caps = MDP_CAP_SMP |
  346. MDP_CAP_SRC_SPLIT |
  347. 0,
  348. },
  349. .smp = {
  350. .mmb_count = 44,
  351. .mmb_size = 8192,
  352. .clients = {
  353. [SSPP_VIG0] = 1, [SSPP_VIG1] = 4,
  354. [SSPP_VIG2] = 7, [SSPP_VIG3] = 19,
  355. [SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
  356. [SSPP_RGB0] = 16, [SSPP_RGB1] = 17,
  357. [SSPP_RGB2] = 18, [SSPP_RGB3] = 22,
  358. },
  359. .reserved_state[0] = GENMASK(23, 0), /* first 24 MMBs */
  360. .reserved = {
  361. [1] = 1, [4] = 1, [7] = 1, [19] = 1,
  362. [16] = 5, [17] = 5, [18] = 5, [22] = 5,
  363. },
  364. },
  365. .ctl = {
  366. .count = 5,
  367. .base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
  368. .flush_hw_mask = 0xf0ffffff,
  369. },
  370. .pipe_vig = {
  371. .count = 4,
  372. .base = { 0x04000, 0x06000, 0x08000, 0x0a000 },
  373. .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
  374. MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
  375. MDP_PIPE_CAP_DECIMATION,
  376. },
  377. .pipe_rgb = {
  378. .count = 4,
  379. .base = { 0x14000, 0x16000, 0x18000, 0x1a000 },
  380. .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
  381. MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
  382. },
  383. .pipe_dma = {
  384. .count = 2,
  385. .base = { 0x24000, 0x26000 },
  386. .caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
  387. },
  388. .lm = {
  389. .count = 6,
  390. .base = { 0x44000, 0x45000, 0x46000, 0x47000, 0x48000, 0x49000 },
  391. .instances = {
  392. { .id = 0, .pp = 0, .dspp = 0,
  393. .caps = MDP_LM_CAP_DISPLAY |
  394. MDP_LM_CAP_PAIR, },
  395. { .id = 1, .pp = 1, .dspp = 1,
  396. .caps = MDP_LM_CAP_DISPLAY, },
  397. { .id = 2, .pp = 2, .dspp = 2,
  398. .caps = MDP_LM_CAP_DISPLAY |
  399. MDP_LM_CAP_PAIR, },
  400. { .id = 3, .pp = -1, .dspp = -1,
  401. .caps = MDP_LM_CAP_WB, },
  402. { .id = 4, .pp = -1, .dspp = -1,
  403. .caps = MDP_LM_CAP_WB, },
  404. { .id = 5, .pp = 3, .dspp = 3,
  405. .caps = MDP_LM_CAP_DISPLAY, },
  406. },
  407. .nb_stages = 8,
  408. .max_width = 2048,
  409. .max_height = 0xFFFF,
  410. },
  411. .dspp = {
  412. .count = 4,
  413. .base = { 0x54000, 0x56000, 0x58000, 0x5a000 },
  414. },
  415. .ad = {
  416. .count = 3,
  417. .base = { 0x78000, 0x78800, 0x79000 },
  418. },
  419. .pp = {
  420. .count = 4,
  421. .base = { 0x70000, 0x70800, 0x71000, 0x71800 },
  422. },
  423. .intf = {
  424. .base = { 0x6a000, 0x6a800, 0x6b000, 0x6b800, 0x6c000 },
  425. .connect = {
  426. [0] = INTF_DISABLED,
  427. [1] = INTF_DSI,
  428. [2] = INTF_DSI,
  429. [3] = INTF_HDMI,
  430. },
  431. },
  432. .max_clk = 400000000,
  433. };
  434. const struct mdp5_cfg_hw msm8x96_config = {
  435. .name = "msm8x96",
  436. .mdp = {
  437. .count = 1,
  438. .caps = MDP_CAP_DSC |
  439. MDP_CAP_CDM |
  440. MDP_CAP_SRC_SPLIT |
  441. 0,
  442. },
  443. .ctl = {
  444. .count = 5,
  445. .base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
  446. .flush_hw_mask = 0xf4ffffff,
  447. },
  448. .pipe_vig = {
  449. .count = 4,
  450. .base = { 0x04000, 0x06000, 0x08000, 0x0a000 },
  451. .caps = MDP_PIPE_CAP_HFLIP |
  452. MDP_PIPE_CAP_VFLIP |
  453. MDP_PIPE_CAP_SCALE |
  454. MDP_PIPE_CAP_CSC |
  455. MDP_PIPE_CAP_DECIMATION |
  456. MDP_PIPE_CAP_SW_PIX_EXT |
  457. 0,
  458. },
  459. .pipe_rgb = {
  460. .count = 4,
  461. .base = { 0x14000, 0x16000, 0x18000, 0x1a000 },
  462. .caps = MDP_PIPE_CAP_HFLIP |
  463. MDP_PIPE_CAP_VFLIP |
  464. MDP_PIPE_CAP_SCALE |
  465. MDP_PIPE_CAP_DECIMATION |
  466. MDP_PIPE_CAP_SW_PIX_EXT |
  467. 0,
  468. },
  469. .pipe_dma = {
  470. .count = 2,
  471. .base = { 0x24000, 0x26000 },
  472. .caps = MDP_PIPE_CAP_HFLIP |
  473. MDP_PIPE_CAP_VFLIP |
  474. MDP_PIPE_CAP_SW_PIX_EXT |
  475. 0,
  476. },
  477. .pipe_cursor = {
  478. .count = 2,
  479. .base = { 0x34000, 0x36000 },
  480. .caps = MDP_PIPE_CAP_HFLIP |
  481. MDP_PIPE_CAP_VFLIP |
  482. MDP_PIPE_CAP_SW_PIX_EXT |
  483. MDP_PIPE_CAP_CURSOR |
  484. 0,
  485. },
  486. .lm = {
  487. .count = 6,
  488. .base = { 0x44000, 0x45000, 0x46000, 0x47000, 0x48000, 0x49000 },
  489. .instances = {
  490. { .id = 0, .pp = 0, .dspp = 0,
  491. .caps = MDP_LM_CAP_DISPLAY |
  492. MDP_LM_CAP_PAIR, },
  493. { .id = 1, .pp = 1, .dspp = 1,
  494. .caps = MDP_LM_CAP_DISPLAY, },
  495. { .id = 2, .pp = 2, .dspp = -1,
  496. .caps = MDP_LM_CAP_DISPLAY |
  497. MDP_LM_CAP_PAIR, },
  498. { .id = 3, .pp = -1, .dspp = -1,
  499. .caps = MDP_LM_CAP_WB, },
  500. { .id = 4, .pp = -1, .dspp = -1,
  501. .caps = MDP_LM_CAP_WB, },
  502. { .id = 5, .pp = 3, .dspp = -1,
  503. .caps = MDP_LM_CAP_DISPLAY, },
  504. },
  505. .nb_stages = 8,
  506. .max_width = 2560,
  507. .max_height = 0xFFFF,
  508. },
  509. .dspp = {
  510. .count = 2,
  511. .base = { 0x54000, 0x56000 },
  512. },
  513. .ad = {
  514. .count = 3,
  515. .base = { 0x78000, 0x78800, 0x79000 },
  516. },
  517. .pp = {
  518. .count = 4,
  519. .base = { 0x70000, 0x70800, 0x71000, 0x71800 },
  520. },
  521. .cdm = {
  522. .count = 1,
  523. .base = { 0x79200 },
  524. },
  525. .dsc = {
  526. .count = 2,
  527. .base = { 0x80000, 0x80400 },
  528. },
  529. .intf = {
  530. .base = { 0x6a000, 0x6a800, 0x6b000, 0x6b800, 0x6c000 },
  531. .connect = {
  532. [0] = INTF_DISABLED,
  533. [1] = INTF_DSI,
  534. [2] = INTF_DSI,
  535. [3] = INTF_HDMI,
  536. },
  537. },
  538. .max_clk = 412500000,
  539. };
  540. static const struct mdp5_cfg_handler cfg_handlers[] = {
  541. { .revision = 0, .config = { .hw = &msm8x74v1_config } },
  542. { .revision = 2, .config = { .hw = &msm8x74v2_config } },
  543. { .revision = 3, .config = { .hw = &apq8084_config } },
  544. { .revision = 6, .config = { .hw = &msm8x16_config } },
  545. { .revision = 9, .config = { .hw = &msm8x94_config } },
  546. { .revision = 7, .config = { .hw = &msm8x96_config } },
  547. };
  548. static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev);
  549. const struct mdp5_cfg_hw *mdp5_cfg_get_hw_config(struct mdp5_cfg_handler *cfg_handler)
  550. {
  551. return cfg_handler->config.hw;
  552. }
  553. struct mdp5_cfg *mdp5_cfg_get_config(struct mdp5_cfg_handler *cfg_handler)
  554. {
  555. return &cfg_handler->config;
  556. }
  557. int mdp5_cfg_get_hw_rev(struct mdp5_cfg_handler *cfg_handler)
  558. {
  559. return cfg_handler->revision;
  560. }
  561. void mdp5_cfg_destroy(struct mdp5_cfg_handler *cfg_handler)
  562. {
  563. kfree(cfg_handler);
  564. }
  565. struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms,
  566. uint32_t major, uint32_t minor)
  567. {
  568. struct drm_device *dev = mdp5_kms->dev;
  569. struct platform_device *pdev = to_platform_device(dev->dev);
  570. struct mdp5_cfg_handler *cfg_handler;
  571. struct mdp5_cfg_platform *pconfig;
  572. int i, ret = 0;
  573. cfg_handler = kzalloc(sizeof(*cfg_handler), GFP_KERNEL);
  574. if (unlikely(!cfg_handler)) {
  575. ret = -ENOMEM;
  576. goto fail;
  577. }
  578. if (major != 1) {
  579. dev_err(dev->dev, "unexpected MDP major version: v%d.%d\n",
  580. major, minor);
  581. ret = -ENXIO;
  582. goto fail;
  583. }
  584. /* only after mdp5_cfg global pointer's init can we access the hw */
  585. for (i = 0; i < ARRAY_SIZE(cfg_handlers); i++) {
  586. if (cfg_handlers[i].revision != minor)
  587. continue;
  588. mdp5_cfg = cfg_handlers[i].config.hw;
  589. break;
  590. }
  591. if (unlikely(!mdp5_cfg)) {
  592. dev_err(dev->dev, "unexpected MDP minor revision: v%d.%d\n",
  593. major, minor);
  594. ret = -ENXIO;
  595. goto fail;
  596. }
  597. cfg_handler->revision = minor;
  598. cfg_handler->config.hw = mdp5_cfg;
  599. pconfig = mdp5_get_config(pdev);
  600. memcpy(&cfg_handler->config.platform, pconfig, sizeof(*pconfig));
  601. DBG("MDP5: %s hw config selected", mdp5_cfg->name);
  602. return cfg_handler;
  603. fail:
  604. if (cfg_handler)
  605. mdp5_cfg_destroy(cfg_handler);
  606. return NULL;
  607. }
  608. static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev)
  609. {
  610. static struct mdp5_cfg_platform config = {};
  611. config.iommu = iommu_domain_alloc(&platform_bus_type);
  612. if (config.iommu) {
  613. config.iommu->geometry.aperture_start = 0x1000;
  614. config.iommu->geometry.aperture_end = 0xffffffff;
  615. }
  616. return &config;
  617. }