sde_formats.c 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
  4. */
  5. #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
  6. #include <drm/drm_fourcc.h>
  7. #include <media/mmm_color_fmt.h>
  8. #include "sde_kms.h"
  9. #include "sde_formats.h"
  10. #define SDE_UBWC_META_MACRO_W_H 16
  11. #define SDE_UBWC_META_BLOCK_SIZE 256
  12. #define SDE_UBWC_PLANE_SIZE_ALIGNMENT 4096
  13. #define SDE_TILE_HEIGHT_DEFAULT 1
  14. #define SDE_TILE_HEIGHT_TILED 4
  15. #define SDE_TILE_HEIGHT_UBWC 4
  16. #define SDE_TILE_HEIGHT_NV12 8
  17. #define SDE_MAX_IMG_WIDTH 0x3FFF
  18. #define SDE_MAX_IMG_HEIGHT 0x3FFF
  19. /**
  20. * SDE supported format packing, bpp, and other format
  21. * information.
  22. * SDE currently only supports interleaved RGB formats
  23. * UBWC support for a pixel format is indicated by the flag,
  24. * there is additional meta data plane for such formats
  25. */
  26. #define INTERLEAVED_RGB_FMT(fmt, a, r, g, b, e0, e1, e2, e3, uc, alpha, \
  27. bp, flg, fm, np) \
  28. { \
  29. .base.pixel_format = DRM_FORMAT_ ## fmt, \
  30. .fetch_planes = SDE_PLANE_INTERLEAVED, \
  31. .alpha_enable = alpha, \
  32. .element = { (e0), (e1), (e2), (e3) }, \
  33. .bits = { g, b, r, a }, \
  34. .chroma_sample = SDE_CHROMA_RGB, \
  35. .unpack_align_msb = 0, \
  36. .unpack_tight = 1, \
  37. .unpack_count = uc, \
  38. .bpp = bp, \
  39. .fetch_mode = fm, \
  40. .flag = {(flg)}, \
  41. .num_planes = np, \
  42. .tile_height = SDE_TILE_HEIGHT_DEFAULT \
  43. }
  44. #define INTERLEAVED_RGB_FMT_TILED(fmt, a, r, g, b, e0, e1, e2, e3, uc, \
  45. alpha, bp, flg, fm, np, th) \
  46. { \
  47. .base.pixel_format = DRM_FORMAT_ ## fmt, \
  48. .fetch_planes = SDE_PLANE_INTERLEAVED, \
  49. .alpha_enable = alpha, \
  50. .element = { (e0), (e1), (e2), (e3) }, \
  51. .bits = { g, b, r, a }, \
  52. .chroma_sample = SDE_CHROMA_RGB, \
  53. .unpack_align_msb = 0, \
  54. .unpack_tight = 1, \
  55. .unpack_count = uc, \
  56. .bpp = bp, \
  57. .fetch_mode = fm, \
  58. .flag = {(flg)}, \
  59. .num_planes = np, \
  60. .tile_height = th \
  61. }
  62. #define INTERLEAVED_YUV_FMT(fmt, a, r, g, b, e0, e1, e2, e3, \
  63. alpha, chroma, count, bp, flg, fm, np) \
  64. { \
  65. .base.pixel_format = DRM_FORMAT_ ## fmt, \
  66. .fetch_planes = SDE_PLANE_INTERLEAVED, \
  67. .alpha_enable = alpha, \
  68. .element = { (e0), (e1), (e2), (e3)}, \
  69. .bits = { g, b, r, a }, \
  70. .chroma_sample = chroma, \
  71. .unpack_align_msb = 0, \
  72. .unpack_tight = 1, \
  73. .unpack_count = count, \
  74. .bpp = bp, \
  75. .fetch_mode = fm, \
  76. .flag = {(flg)}, \
  77. .num_planes = np, \
  78. .tile_height = SDE_TILE_HEIGHT_DEFAULT \
  79. }
  80. #define PSEUDO_YUV_FMT(fmt, a, r, g, b, e0, e1, chroma, flg, fm, np) \
  81. { \
  82. .base.pixel_format = DRM_FORMAT_ ## fmt, \
  83. .fetch_planes = SDE_PLANE_PSEUDO_PLANAR, \
  84. .alpha_enable = false, \
  85. .element = { (e0), (e1), 0, 0 }, \
  86. .bits = { g, b, r, a }, \
  87. .chroma_sample = chroma, \
  88. .unpack_align_msb = 0, \
  89. .unpack_tight = 1, \
  90. .unpack_count = 2, \
  91. .bpp = 2, \
  92. .fetch_mode = fm, \
  93. .flag = {(flg)}, \
  94. .num_planes = np, \
  95. .tile_height = SDE_TILE_HEIGHT_DEFAULT \
  96. }
  97. #define PSEUDO_YUV_FMT_TILED(fmt, a, r, g, b, e0, e1, chroma, \
  98. flg, fm, np, th) \
  99. { \
  100. .base.pixel_format = DRM_FORMAT_ ## fmt, \
  101. .fetch_planes = SDE_PLANE_PSEUDO_PLANAR, \
  102. .alpha_enable = false, \
  103. .element = { (e0), (e1), 0, 0 }, \
  104. .bits = { g, b, r, a }, \
  105. .chroma_sample = chroma, \
  106. .unpack_align_msb = 0, \
  107. .unpack_tight = 1, \
  108. .unpack_count = 2, \
  109. .bpp = 2, \
  110. .fetch_mode = fm, \
  111. .flag = {(flg)}, \
  112. .num_planes = np, \
  113. .tile_height = th \
  114. }
  115. #define PSEUDO_YUV_FMT_LOOSE(fmt, a, r, g, b, e0, e1, chroma, flg, fm, np)\
  116. { \
  117. .base.pixel_format = DRM_FORMAT_ ## fmt, \
  118. .fetch_planes = SDE_PLANE_PSEUDO_PLANAR, \
  119. .alpha_enable = false, \
  120. .element = { (e0), (e1), 0, 0 }, \
  121. .bits = { g, b, r, a }, \
  122. .chroma_sample = chroma, \
  123. .unpack_align_msb = 1, \
  124. .unpack_tight = 0, \
  125. .unpack_count = 2, \
  126. .bpp = 2, \
  127. .fetch_mode = fm, \
  128. .flag = {(flg)}, \
  129. .num_planes = np, \
  130. .tile_height = SDE_TILE_HEIGHT_DEFAULT \
  131. }
  132. #define PSEUDO_YUV_FMT_LOOSE_TILED(fmt, a, r, g, b, e0, e1, chroma, \
  133. flg, fm, np, th) \
  134. { \
  135. .base.pixel_format = DRM_FORMAT_ ## fmt, \
  136. .fetch_planes = SDE_PLANE_PSEUDO_PLANAR, \
  137. .alpha_enable = false, \
  138. .element = { (e0), (e1), 0, 0 }, \
  139. .bits = { g, b, r, a }, \
  140. .chroma_sample = chroma, \
  141. .unpack_align_msb = 1, \
  142. .unpack_tight = 0, \
  143. .unpack_count = 2, \
  144. .bpp = 2, \
  145. .fetch_mode = fm, \
  146. .flag = {(flg)}, \
  147. .num_planes = np, \
  148. .tile_height = th \
  149. }
  150. #define PLANAR_YUV_FMT(fmt, a, r, g, b, e0, e1, e2, alpha, chroma, bp, \
  151. flg, fm, np) \
  152. { \
  153. .base.pixel_format = DRM_FORMAT_ ## fmt, \
  154. .fetch_planes = SDE_PLANE_PLANAR, \
  155. .alpha_enable = alpha, \
  156. .element = { (e0), (e1), (e2), 0 }, \
  157. .bits = { g, b, r, a }, \
  158. .chroma_sample = chroma, \
  159. .unpack_align_msb = 0, \
  160. .unpack_tight = 1, \
  161. .unpack_count = 1, \
  162. .bpp = bp, \
  163. .fetch_mode = fm, \
  164. .flag = {(flg)}, \
  165. .num_planes = np, \
  166. .tile_height = SDE_TILE_HEIGHT_DEFAULT \
  167. }
  168. /*
  169. * struct sde_media_color_map - maps drm format to media format
  170. * @format: DRM base pixel format
  171. * @color: Media API color related to DRM format
  172. */
  173. struct sde_media_color_map {
  174. uint32_t format;
  175. uint32_t color;
  176. };
  177. static const struct sde_format sde_format_map[] = {
  178. INTERLEAVED_RGB_FMT(ARGB8888,
  179. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  180. C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
  181. true, 4, 0,
  182. SDE_FETCH_LINEAR, 1),
  183. INTERLEAVED_RGB_FMT(ABGR8888,
  184. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  185. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  186. true, 4, 0,
  187. SDE_FETCH_LINEAR, 1),
  188. INTERLEAVED_RGB_FMT(XBGR8888,
  189. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  190. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  191. true, 4, 0,
  192. SDE_FETCH_LINEAR, 1),
  193. INTERLEAVED_RGB_FMT(RGBA8888,
  194. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  195. C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
  196. true, 4, 0,
  197. SDE_FETCH_LINEAR, 1),
  198. INTERLEAVED_RGB_FMT(BGRA8888,
  199. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  200. C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
  201. true, 4, 0,
  202. SDE_FETCH_LINEAR, 1),
  203. INTERLEAVED_RGB_FMT(BGRX8888,
  204. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  205. C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
  206. false, 4, 0,
  207. SDE_FETCH_LINEAR, 1),
  208. INTERLEAVED_RGB_FMT(XRGB8888,
  209. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  210. C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
  211. false, 4, 0,
  212. SDE_FETCH_LINEAR, 1),
  213. INTERLEAVED_RGB_FMT(RGBX8888,
  214. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  215. C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
  216. false, 4, 0,
  217. SDE_FETCH_LINEAR, 1),
  218. INTERLEAVED_RGB_FMT(RGB888,
  219. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  220. C1_B_Cb, C0_G_Y, C2_R_Cr, 0, 3,
  221. false, 3, 0,
  222. SDE_FETCH_LINEAR, 1),
  223. INTERLEAVED_RGB_FMT(BGR888,
  224. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  225. C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
  226. false, 3, 0,
  227. SDE_FETCH_LINEAR, 1),
  228. INTERLEAVED_RGB_FMT(RGB565,
  229. 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
  230. C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
  231. false, 2, 0,
  232. SDE_FETCH_LINEAR, 1),
  233. INTERLEAVED_RGB_FMT(BGR565,
  234. 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
  235. C1_B_Cb, C0_G_Y, C2_R_Cr, 0, 3,
  236. false, 2, 0,
  237. SDE_FETCH_LINEAR, 1),
  238. INTERLEAVED_RGB_FMT(ARGB1555,
  239. COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
  240. C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
  241. true, 2, 0,
  242. SDE_FETCH_LINEAR, 1),
  243. INTERLEAVED_RGB_FMT(ABGR1555,
  244. COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
  245. C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
  246. true, 2, 0,
  247. SDE_FETCH_LINEAR, 1),
  248. INTERLEAVED_RGB_FMT(RGBA5551,
  249. COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
  250. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  251. true, 2, 0,
  252. SDE_FETCH_LINEAR, 1),
  253. INTERLEAVED_RGB_FMT(BGRA5551,
  254. COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
  255. C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
  256. true, 2, 0,
  257. SDE_FETCH_LINEAR, 1),
  258. INTERLEAVED_RGB_FMT(XRGB1555,
  259. COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
  260. C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
  261. false, 2, 0,
  262. SDE_FETCH_LINEAR, 1),
  263. INTERLEAVED_RGB_FMT(XBGR1555,
  264. COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
  265. C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
  266. false, 2, 0,
  267. SDE_FETCH_LINEAR, 1),
  268. INTERLEAVED_RGB_FMT(RGBX5551,
  269. COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
  270. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  271. false, 2, 0,
  272. SDE_FETCH_LINEAR, 1),
  273. INTERLEAVED_RGB_FMT(BGRX5551,
  274. COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
  275. C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
  276. false, 2, 0,
  277. SDE_FETCH_LINEAR, 1),
  278. INTERLEAVED_RGB_FMT(ARGB4444,
  279. COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
  280. C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
  281. true, 2, 0,
  282. SDE_FETCH_LINEAR, 1),
  283. INTERLEAVED_RGB_FMT(ABGR4444,
  284. COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
  285. C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
  286. true, 2, 0,
  287. SDE_FETCH_LINEAR, 1),
  288. INTERLEAVED_RGB_FMT(RGBA4444,
  289. COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
  290. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  291. true, 2, 0,
  292. SDE_FETCH_LINEAR, 1),
  293. INTERLEAVED_RGB_FMT(BGRA4444,
  294. COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
  295. C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
  296. true, 2, 0,
  297. SDE_FETCH_LINEAR, 1),
  298. INTERLEAVED_RGB_FMT(XRGB4444,
  299. COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
  300. C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
  301. false, 2, 0,
  302. SDE_FETCH_LINEAR, 1),
  303. INTERLEAVED_RGB_FMT(XBGR4444,
  304. COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
  305. C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
  306. false, 2, 0,
  307. SDE_FETCH_LINEAR, 1),
  308. INTERLEAVED_RGB_FMT(RGBX4444,
  309. COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
  310. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  311. false, 2, 0,
  312. SDE_FETCH_LINEAR, 1),
  313. INTERLEAVED_RGB_FMT(BGRX4444,
  314. COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
  315. C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
  316. false, 2, 0,
  317. SDE_FETCH_LINEAR, 1),
  318. INTERLEAVED_RGB_FMT(BGRA1010102,
  319. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  320. C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
  321. true, 4, SDE_FORMAT_FLAG_DX,
  322. SDE_FETCH_LINEAR, 1),
  323. INTERLEAVED_RGB_FMT(RGBA1010102,
  324. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  325. C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
  326. true, 4, SDE_FORMAT_FLAG_DX,
  327. SDE_FETCH_LINEAR, 1),
  328. INTERLEAVED_RGB_FMT(ABGR2101010,
  329. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  330. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  331. true, 4, SDE_FORMAT_FLAG_DX,
  332. SDE_FETCH_LINEAR, 1),
  333. INTERLEAVED_RGB_FMT(ARGB2101010,
  334. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  335. C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
  336. true, 4, SDE_FORMAT_FLAG_DX,
  337. SDE_FETCH_LINEAR, 1),
  338. INTERLEAVED_RGB_FMT(XRGB2101010,
  339. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  340. C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
  341. false, 4, SDE_FORMAT_FLAG_DX,
  342. SDE_FETCH_LINEAR, 1),
  343. INTERLEAVED_RGB_FMT(BGRX1010102,
  344. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  345. C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
  346. false, 4, SDE_FORMAT_FLAG_DX,
  347. SDE_FETCH_LINEAR, 1),
  348. INTERLEAVED_RGB_FMT(XBGR2101010,
  349. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  350. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  351. false, 4, SDE_FORMAT_FLAG_DX,
  352. SDE_FETCH_LINEAR, 1),
  353. INTERLEAVED_RGB_FMT(RGBX1010102,
  354. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  355. C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
  356. false, 4, SDE_FORMAT_FLAG_DX,
  357. SDE_FETCH_LINEAR, 1),
  358. INTERLEAVED_RGB_FMT(ARGB16161616F,
  359. COLOR_16BIT, COLOR_16BIT, COLOR_16BIT, COLOR_16BIT,
  360. C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
  361. true, 8, SDE_FORMAT_FLAG_FP16,
  362. SDE_FETCH_LINEAR, 1),
  363. INTERLEAVED_RGB_FMT(ABGR16161616F,
  364. COLOR_16BIT, COLOR_16BIT, COLOR_16BIT, COLOR_16BIT,
  365. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  366. true, 8, SDE_FORMAT_FLAG_FP16,
  367. SDE_FETCH_LINEAR, 1),
  368. PSEUDO_YUV_FMT(NV12,
  369. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  370. C1_B_Cb, C2_R_Cr,
  371. SDE_CHROMA_420, SDE_FORMAT_FLAG_YUV,
  372. SDE_FETCH_LINEAR, 2),
  373. PSEUDO_YUV_FMT(NV21,
  374. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  375. C2_R_Cr, C1_B_Cb,
  376. SDE_CHROMA_420, SDE_FORMAT_FLAG_YUV,
  377. SDE_FETCH_LINEAR, 2),
  378. PSEUDO_YUV_FMT(NV16,
  379. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  380. C1_B_Cb, C2_R_Cr,
  381. SDE_CHROMA_H2V1, SDE_FORMAT_FLAG_YUV,
  382. SDE_FETCH_LINEAR, 2),
  383. PSEUDO_YUV_FMT(NV61,
  384. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  385. C2_R_Cr, C1_B_Cb,
  386. SDE_CHROMA_H2V1, SDE_FORMAT_FLAG_YUV,
  387. SDE_FETCH_LINEAR, 2),
  388. INTERLEAVED_YUV_FMT(VYUY,
  389. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  390. C2_R_Cr, C0_G_Y, C1_B_Cb, C0_G_Y,
  391. false, SDE_CHROMA_H2V1, 4, 2, SDE_FORMAT_FLAG_YUV,
  392. SDE_FETCH_LINEAR, 2),
  393. INTERLEAVED_YUV_FMT(UYVY,
  394. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  395. C1_B_Cb, C0_G_Y, C2_R_Cr, C0_G_Y,
  396. false, SDE_CHROMA_H2V1, 4, 2, SDE_FORMAT_FLAG_YUV,
  397. SDE_FETCH_LINEAR, 2),
  398. INTERLEAVED_YUV_FMT(YUYV,
  399. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  400. C0_G_Y, C1_B_Cb, C0_G_Y, C2_R_Cr,
  401. false, SDE_CHROMA_H2V1, 4, 2, SDE_FORMAT_FLAG_YUV,
  402. SDE_FETCH_LINEAR, 2),
  403. INTERLEAVED_YUV_FMT(YVYU,
  404. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  405. C0_G_Y, C2_R_Cr, C0_G_Y, C1_B_Cb,
  406. false, SDE_CHROMA_H2V1, 4, 2, SDE_FORMAT_FLAG_YUV,
  407. SDE_FETCH_LINEAR, 2),
  408. PLANAR_YUV_FMT(YUV420,
  409. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  410. C2_R_Cr, C1_B_Cb, C0_G_Y,
  411. false, SDE_CHROMA_420, 1, SDE_FORMAT_FLAG_YUV,
  412. SDE_FETCH_LINEAR, 3),
  413. PLANAR_YUV_FMT(YVU420,
  414. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  415. C1_B_Cb, C2_R_Cr, C0_G_Y,
  416. false, SDE_CHROMA_420, 1, SDE_FORMAT_FLAG_YUV,
  417. SDE_FETCH_LINEAR, 3),
  418. };
  419. /* Base formats supporting the alpha swapping modifier */
  420. static const struct sde_format sde_format_map_alpha_swap[] = {
  421. INTERLEAVED_RGB_FMT(ARGB16161616F,
  422. COLOR_16BIT, COLOR_16BIT, COLOR_16BIT, COLOR_16BIT,
  423. C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
  424. true, 8, SDE_FORMAT_FLAG_FP16 | SDE_FORMAT_FLAG_ALPHA_SWAP,
  425. SDE_FETCH_LINEAR, 1),
  426. INTERLEAVED_RGB_FMT(ABGR16161616F,
  427. COLOR_16BIT, COLOR_16BIT, COLOR_16BIT, COLOR_16BIT,
  428. C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
  429. true, 8, SDE_FORMAT_FLAG_FP16 | SDE_FORMAT_FLAG_ALPHA_SWAP,
  430. SDE_FETCH_LINEAR, 1),
  431. };
  432. /*
  433. * A5x tile formats tables:
  434. * These tables hold the A5x tile formats supported.
  435. */
  436. static const struct sde_format sde_format_map_tile[] = {
  437. INTERLEAVED_RGB_FMT_TILED(BGR565,
  438. 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
  439. C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
  440. false, 2, 0,
  441. SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
  442. INTERLEAVED_RGB_FMT_TILED(ARGB8888,
  443. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  444. C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
  445. true, 4, 0,
  446. SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
  447. INTERLEAVED_RGB_FMT_TILED(ABGR8888,
  448. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  449. C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
  450. true, 4, 0,
  451. SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
  452. INTERLEAVED_RGB_FMT_TILED(XBGR8888,
  453. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  454. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  455. false, 4, 0,
  456. SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
  457. INTERLEAVED_RGB_FMT_TILED(RGBA8888,
  458. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  459. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  460. true, 4, 0,
  461. SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
  462. INTERLEAVED_RGB_FMT_TILED(BGRA8888,
  463. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  464. C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
  465. true, 4, 0,
  466. SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
  467. INTERLEAVED_RGB_FMT_TILED(BGRX8888,
  468. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  469. C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
  470. false, 4, 0,
  471. SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
  472. INTERLEAVED_RGB_FMT_TILED(XRGB8888,
  473. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  474. C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
  475. false, 4, 0,
  476. SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
  477. INTERLEAVED_RGB_FMT_TILED(RGBX8888,
  478. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  479. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  480. false, 4, 0,
  481. SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
  482. INTERLEAVED_RGB_FMT_TILED(ABGR2101010,
  483. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  484. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  485. true, 4, SDE_FORMAT_FLAG_DX,
  486. SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
  487. INTERLEAVED_RGB_FMT_TILED(XBGR2101010,
  488. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  489. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  490. true, 4, SDE_FORMAT_FLAG_DX,
  491. SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
  492. PSEUDO_YUV_FMT_TILED(NV12,
  493. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  494. C1_B_Cb, C2_R_Cr,
  495. SDE_CHROMA_420, SDE_FORMAT_FLAG_YUV,
  496. SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_NV12),
  497. PSEUDO_YUV_FMT_TILED(NV21,
  498. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  499. C2_R_Cr, C1_B_Cb,
  500. SDE_CHROMA_420, SDE_FORMAT_FLAG_YUV,
  501. SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_NV12),
  502. };
  503. static const struct sde_format sde_format_map_p010_tile[] = {
  504. PSEUDO_YUV_FMT_LOOSE_TILED(NV12,
  505. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  506. C1_B_Cb, C2_R_Cr,
  507. SDE_CHROMA_420, (SDE_FORMAT_FLAG_YUV | SDE_FORMAT_FLAG_DX),
  508. SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_NV12),
  509. };
  510. static const struct sde_format sde_format_map_tp10_tile[] = {
  511. PSEUDO_YUV_FMT_TILED(NV12,
  512. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  513. C1_B_Cb, C2_R_Cr,
  514. SDE_CHROMA_420, (SDE_FORMAT_FLAG_YUV | SDE_FORMAT_FLAG_DX),
  515. SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_NV12),
  516. };
  517. /*
  518. * UBWC formats table:
  519. * This table holds the UBWC formats supported.
  520. * If a compression ratio needs to be used for this or any other format,
  521. * the data will be passed by user-space.
  522. */
  523. static const struct sde_format sde_format_map_ubwc[] = {
  524. INTERLEAVED_RGB_FMT_TILED(BGR565,
  525. 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
  526. C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
  527. false, 2, SDE_FORMAT_FLAG_COMPRESSED,
  528. SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_UBWC),
  529. INTERLEAVED_RGB_FMT_TILED(ABGR8888,
  530. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  531. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  532. true, 4, SDE_FORMAT_FLAG_COMPRESSED,
  533. SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_UBWC),
  534. INTERLEAVED_RGB_FMT_TILED(XBGR8888,
  535. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  536. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  537. false, 4, SDE_FORMAT_FLAG_COMPRESSED,
  538. SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_UBWC),
  539. INTERLEAVED_RGB_FMT_TILED(ABGR2101010,
  540. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  541. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  542. true, 4, SDE_FORMAT_FLAG_DX | SDE_FORMAT_FLAG_COMPRESSED,
  543. SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_UBWC),
  544. INTERLEAVED_RGB_FMT_TILED(XBGR2101010,
  545. COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  546. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  547. true, 4, SDE_FORMAT_FLAG_DX | SDE_FORMAT_FLAG_COMPRESSED,
  548. SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_UBWC),
  549. INTERLEAVED_RGB_FMT_TILED(ABGR16161616F,
  550. COLOR_16BIT, COLOR_16BIT, COLOR_16BIT, COLOR_16BIT,
  551. C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
  552. true, 8, SDE_FORMAT_FLAG_FP16 | SDE_FORMAT_FLAG_COMPRESSED,
  553. SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_UBWC),
  554. PSEUDO_YUV_FMT_TILED(NV12,
  555. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  556. C1_B_Cb, C2_R_Cr,
  557. SDE_CHROMA_420, SDE_FORMAT_FLAG_YUV |
  558. SDE_FORMAT_FLAG_COMPRESSED,
  559. SDE_FETCH_UBWC, 4, SDE_TILE_HEIGHT_NV12),
  560. };
  561. static const struct sde_format sde_format_map_p010[] = {
  562. PSEUDO_YUV_FMT_LOOSE(NV12,
  563. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  564. C1_B_Cb, C2_R_Cr,
  565. SDE_CHROMA_420, (SDE_FORMAT_FLAG_YUV | SDE_FORMAT_FLAG_DX),
  566. SDE_FETCH_LINEAR, 2),
  567. };
  568. static const struct sde_format sde_format_map_p010_ubwc[] = {
  569. PSEUDO_YUV_FMT_LOOSE_TILED(NV12,
  570. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  571. C1_B_Cb, C2_R_Cr,
  572. SDE_CHROMA_420, (SDE_FORMAT_FLAG_YUV | SDE_FORMAT_FLAG_DX |
  573. SDE_FORMAT_FLAG_COMPRESSED),
  574. SDE_FETCH_UBWC, 4, SDE_TILE_HEIGHT_NV12),
  575. };
  576. static const struct sde_format sde_format_map_tp10_ubwc[] = {
  577. PSEUDO_YUV_FMT_TILED(NV12,
  578. 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
  579. C1_B_Cb, C2_R_Cr,
  580. SDE_CHROMA_420, (SDE_FORMAT_FLAG_YUV | SDE_FORMAT_FLAG_DX |
  581. SDE_FORMAT_FLAG_COMPRESSED),
  582. SDE_FETCH_UBWC, 4, SDE_TILE_HEIGHT_NV12),
  583. };
  584. bool sde_format_is_tp10_ubwc(const struct sde_format *fmt)
  585. {
  586. if (SDE_FORMAT_IS_YUV(fmt) && SDE_FORMAT_IS_DX(fmt) &&
  587. SDE_FORMAT_IS_UBWC(fmt) &&
  588. (fmt->num_planes == 4) && fmt->unpack_tight)
  589. return true;
  590. else
  591. return false;
  592. }
  593. /* _sde_get_v_h_subsample_rate - Get subsample rates for all formats we support
  594. * Note: Not using the drm_format_*_subsampling since we have formats
  595. */
  596. static void _sde_get_v_h_subsample_rate(
  597. enum sde_chroma_samp_type chroma_sample,
  598. uint32_t *v_sample,
  599. uint32_t *h_sample)
  600. {
  601. if (!v_sample || !h_sample)
  602. return;
  603. switch (chroma_sample) {
  604. case SDE_CHROMA_H2V1:
  605. *v_sample = 1;
  606. *h_sample = 2;
  607. break;
  608. case SDE_CHROMA_H1V2:
  609. *v_sample = 2;
  610. *h_sample = 1;
  611. break;
  612. case SDE_CHROMA_420:
  613. *v_sample = 2;
  614. *h_sample = 2;
  615. break;
  616. default:
  617. *v_sample = 1;
  618. *h_sample = 1;
  619. break;
  620. }
  621. }
  622. static int _sde_format_get_media_color_ubwc(const struct sde_format *fmt)
  623. {
  624. static const struct sde_media_color_map sde_media_ubwc_map[] = {
  625. {DRM_FORMAT_ABGR8888, MMM_COLOR_FMT_RGBA8888_UBWC},
  626. {DRM_FORMAT_XBGR8888, MMM_COLOR_FMT_RGBA8888_UBWC},
  627. {DRM_FORMAT_ABGR2101010, MMM_COLOR_FMT_RGBA1010102_UBWC},
  628. {DRM_FORMAT_XBGR2101010, MMM_COLOR_FMT_RGBA1010102_UBWC},
  629. {DRM_FORMAT_BGR565, MMM_COLOR_FMT_RGB565_UBWC},
  630. {DRM_FORMAT_ABGR16161616F, MMM_COLOR_FMT_RGBA16161616F_UBWC},
  631. };
  632. int color_fmt = -1;
  633. int i;
  634. if (fmt->base.pixel_format == DRM_FORMAT_NV12) {
  635. if (SDE_FORMAT_IS_DX(fmt)) {
  636. if (fmt->unpack_tight)
  637. color_fmt = MMM_COLOR_FMT_NV12_BPP10_UBWC;
  638. else
  639. color_fmt = MMM_COLOR_FMT_P010_UBWC;
  640. } else
  641. color_fmt = MMM_COLOR_FMT_NV12_UBWC;
  642. return color_fmt;
  643. }
  644. for (i = 0; i < ARRAY_SIZE(sde_media_ubwc_map); ++i)
  645. if (fmt->base.pixel_format == sde_media_ubwc_map[i].format) {
  646. color_fmt = sde_media_ubwc_map[i].color;
  647. break;
  648. }
  649. return color_fmt;
  650. }
  651. static int _sde_format_get_plane_sizes_ubwc(
  652. const struct sde_format *fmt,
  653. const uint32_t width,
  654. const uint32_t height,
  655. struct sde_hw_fmt_layout *layout)
  656. {
  657. int i;
  658. int color;
  659. bool meta = SDE_FORMAT_IS_UBWC(fmt);
  660. memset(layout, 0, sizeof(struct sde_hw_fmt_layout));
  661. layout->format = fmt;
  662. layout->width = width;
  663. layout->height = height;
  664. layout->num_planes = fmt->num_planes;
  665. color = _sde_format_get_media_color_ubwc(fmt);
  666. if (color < 0) {
  667. DRM_ERROR("UBWC format not supported for fmt: %4.4s\n",
  668. (char *)&fmt->base.pixel_format);
  669. return -EINVAL;
  670. }
  671. if (SDE_FORMAT_IS_YUV(layout->format)) {
  672. uint32_t y_sclines, uv_sclines;
  673. uint32_t y_meta_scanlines = 0;
  674. uint32_t uv_meta_scanlines = 0;
  675. layout->num_planes = 2;
  676. layout->plane_pitch[0] = MMM_COLOR_FMT_Y_STRIDE(color, width);
  677. y_sclines = MMM_COLOR_FMT_Y_SCANLINES(color, height);
  678. layout->plane_size[0] =
  679. MMM_COLOR_FMT_ALIGN(layout->plane_pitch[0] *
  680. y_sclines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
  681. layout->plane_pitch[1] = MMM_COLOR_FMT_UV_STRIDE(color, width);
  682. uv_sclines = MMM_COLOR_FMT_UV_SCANLINES(color, height);
  683. layout->plane_size[1] =
  684. MMM_COLOR_FMT_ALIGN(layout->plane_pitch[1] *
  685. uv_sclines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
  686. if (!meta)
  687. goto done;
  688. layout->num_planes += 2;
  689. layout->plane_pitch[2] =
  690. MMM_COLOR_FMT_Y_META_STRIDE(color, width);
  691. y_meta_scanlines =
  692. MMM_COLOR_FMT_Y_META_SCANLINES(color, height);
  693. layout->plane_size[2] =
  694. MMM_COLOR_FMT_ALIGN(layout->plane_pitch[2] *
  695. y_meta_scanlines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
  696. layout->plane_pitch[3] =
  697. MMM_COLOR_FMT_UV_META_STRIDE(color, width);
  698. uv_meta_scanlines =
  699. MMM_COLOR_FMT_UV_META_SCANLINES(color, height);
  700. layout->plane_size[3] =
  701. MMM_COLOR_FMT_ALIGN(layout->plane_pitch[3] *
  702. uv_meta_scanlines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
  703. } else {
  704. uint32_t rgb_scanlines, rgb_meta_scanlines;
  705. layout->num_planes = 1;
  706. layout->plane_pitch[0] =
  707. MMM_COLOR_FMT_RGB_STRIDE(color, width);
  708. rgb_scanlines = MMM_COLOR_FMT_RGB_SCANLINES(color, height);
  709. layout->plane_size[0] =
  710. MMM_COLOR_FMT_ALIGN(layout->plane_pitch[0] *
  711. rgb_scanlines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
  712. if (!meta)
  713. goto done;
  714. layout->num_planes += 2;
  715. layout->plane_pitch[2] =
  716. MMM_COLOR_FMT_RGB_META_STRIDE(color, width);
  717. rgb_meta_scanlines =
  718. MMM_COLOR_FMT_RGB_META_SCANLINES(color, height);
  719. layout->plane_size[2] =
  720. MMM_COLOR_FMT_ALIGN(layout->plane_pitch[2] *
  721. rgb_meta_scanlines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
  722. }
  723. done:
  724. for (i = 0; i < SDE_MAX_PLANES; i++)
  725. layout->total_size += layout->plane_size[i];
  726. return 0;
  727. }
  728. static int _sde_format_get_plane_sizes_linear(
  729. const struct sde_format *fmt,
  730. const uint32_t width,
  731. const uint32_t height,
  732. struct sde_hw_fmt_layout *layout,
  733. const uint32_t *pitches)
  734. {
  735. int i;
  736. memset(layout, 0, sizeof(struct sde_hw_fmt_layout));
  737. layout->format = fmt;
  738. layout->width = width;
  739. layout->height = height;
  740. layout->num_planes = fmt->num_planes;
  741. /* Due to memset above, only need to set planes of interest */
  742. if (fmt->fetch_planes == SDE_PLANE_INTERLEAVED) {
  743. layout->num_planes = 1;
  744. layout->plane_size[0] = width * height * layout->format->bpp;
  745. layout->plane_pitch[0] = width * layout->format->bpp;
  746. } else {
  747. uint32_t v_subsample, h_subsample;
  748. uint32_t chroma_samp;
  749. uint32_t bpp = 1;
  750. chroma_samp = fmt->chroma_sample;
  751. _sde_get_v_h_subsample_rate(chroma_samp, &v_subsample,
  752. &h_subsample);
  753. if (width % h_subsample || height % v_subsample) {
  754. DRM_ERROR("mismatch in subsample vs dimensions\n");
  755. return -EINVAL;
  756. }
  757. if ((fmt->base.pixel_format == DRM_FORMAT_NV12) &&
  758. (SDE_FORMAT_IS_DX(fmt)))
  759. bpp = 2;
  760. layout->plane_pitch[0] = width * bpp;
  761. layout->plane_pitch[1] = layout->plane_pitch[0] / h_subsample;
  762. layout->plane_size[0] = layout->plane_pitch[0] * height;
  763. layout->plane_size[1] = layout->plane_pitch[1] *
  764. (height / v_subsample);
  765. if (fmt->fetch_planes == SDE_PLANE_PSEUDO_PLANAR) {
  766. layout->num_planes = 2;
  767. layout->plane_size[1] *= 2;
  768. layout->plane_pitch[1] *= 2;
  769. } else {
  770. /* planar */
  771. layout->num_planes = 3;
  772. layout->plane_size[2] = layout->plane_size[1];
  773. layout->plane_pitch[2] = layout->plane_pitch[1];
  774. }
  775. }
  776. /*
  777. * linear format: allow user allocated pitches if they are greater than
  778. * the requirement.
  779. * ubwc format: pitch values are computed uniformly across
  780. * all the components based on ubwc specifications.
  781. */
  782. for (i = 0; i < layout->num_planes && i < SDE_MAX_PLANES; ++i) {
  783. if (pitches && layout->plane_pitch[i] < pitches[i])
  784. layout->plane_pitch[i] = pitches[i];
  785. }
  786. for (i = 0; i < SDE_MAX_PLANES; i++)
  787. layout->total_size += layout->plane_size[i];
  788. return 0;
  789. }
  790. int sde_format_get_plane_sizes(
  791. const struct sde_format *fmt,
  792. const uint32_t w,
  793. const uint32_t h,
  794. struct sde_hw_fmt_layout *layout,
  795. const uint32_t *pitches)
  796. {
  797. if (!layout || !fmt) {
  798. DRM_ERROR("invalid pointer\n");
  799. return -EINVAL;
  800. }
  801. if ((w > SDE_MAX_IMG_WIDTH) || (h > SDE_MAX_IMG_HEIGHT)) {
  802. DRM_ERROR("image dimensions outside max range\n");
  803. return -ERANGE;
  804. }
  805. if (SDE_FORMAT_IS_UBWC(fmt) || SDE_FORMAT_IS_TILE(fmt))
  806. return _sde_format_get_plane_sizes_ubwc(fmt, w, h, layout);
  807. return _sde_format_get_plane_sizes_linear(fmt, w, h, layout, pitches);
  808. }
  809. int sde_format_get_block_size(const struct sde_format *fmt,
  810. uint32_t *w, uint32_t *h)
  811. {
  812. if (!fmt || !w || !h) {
  813. DRM_ERROR("invalid pointer\n");
  814. return -EINVAL;
  815. }
  816. /* TP10 is 96x96 and all others are 128x128 */
  817. if (SDE_FORMAT_IS_YUV(fmt) && SDE_FORMAT_IS_DX(fmt) &&
  818. (fmt->num_planes == 2) && fmt->unpack_tight)
  819. *w = *h = 96;
  820. else
  821. *w = *h = 128;
  822. return 0;
  823. }
  824. uint32_t sde_format_get_framebuffer_size(
  825. const uint32_t format,
  826. const uint32_t width,
  827. const uint32_t height,
  828. const uint32_t *pitches,
  829. const uint64_t modifier)
  830. {
  831. const struct sde_format *fmt;
  832. struct sde_hw_fmt_layout layout;
  833. fmt = sde_get_sde_format_ext(format, modifier);
  834. if (!fmt)
  835. return 0;
  836. if (!pitches)
  837. return -EINVAL;
  838. if (sde_format_get_plane_sizes(fmt, width, height, &layout, pitches))
  839. layout.total_size = 0;
  840. return layout.total_size;
  841. }
  842. static int _sde_format_populate_addrs_ubwc(
  843. struct msm_gem_address_space *aspace,
  844. struct drm_framebuffer *fb,
  845. struct sde_hw_fmt_layout *layout)
  846. {
  847. uint32_t base_addr;
  848. bool meta;
  849. if (!fb || !layout) {
  850. DRM_ERROR("invalid pointers\n");
  851. return -EINVAL;
  852. }
  853. if (aspace)
  854. base_addr = msm_framebuffer_iova(fb, aspace, 0);
  855. else
  856. base_addr = msm_framebuffer_phys(fb, 0);
  857. if (!base_addr) {
  858. DRM_ERROR("failed to retrieve base addr\n");
  859. return -EFAULT;
  860. }
  861. meta = SDE_FORMAT_IS_UBWC(layout->format);
  862. /* Per-format logic for verifying active planes */
  863. if (SDE_FORMAT_IS_YUV(layout->format)) {
  864. /************************************************/
  865. /* UBWC ** */
  866. /* buffer ** SDE PLANE */
  867. /* format ** */
  868. /************************************************/
  869. /* ------------------- ** -------------------- */
  870. /* | Y meta | ** | Y bitstream | */
  871. /* | data | ** | plane | */
  872. /* ------------------- ** -------------------- */
  873. /* | Y bitstream | ** | CbCr bitstream | */
  874. /* | data | ** | plane | */
  875. /* ------------------- ** -------------------- */
  876. /* | Cbcr metadata | ** | Y meta | */
  877. /* | data | ** | plane | */
  878. /* ------------------- ** -------------------- */
  879. /* | CbCr bitstream | ** | CbCr meta | */
  880. /* | data | ** | plane | */
  881. /* ------------------- ** -------------------- */
  882. /************************************************/
  883. /* configure Y bitstream plane */
  884. layout->plane_addr[0] = base_addr + layout->plane_size[2];
  885. /* configure CbCr bitstream plane */
  886. layout->plane_addr[1] = base_addr + layout->plane_size[0]
  887. + layout->plane_size[2] + layout->plane_size[3];
  888. if (!meta)
  889. goto done;
  890. /* configure Y metadata plane */
  891. layout->plane_addr[2] = base_addr;
  892. /* configure CbCr metadata plane */
  893. layout->plane_addr[3] = base_addr + layout->plane_size[0]
  894. + layout->plane_size[2];
  895. } else {
  896. /************************************************/
  897. /* UBWC ** */
  898. /* buffer ** SDE PLANE */
  899. /* format ** */
  900. /************************************************/
  901. /* ------------------- ** -------------------- */
  902. /* | RGB meta | ** | RGB bitstream | */
  903. /* | data | ** | plane | */
  904. /* ------------------- ** -------------------- */
  905. /* | RGB bitstream | ** | NONE | */
  906. /* | data | ** | | */
  907. /* ------------------- ** -------------------- */
  908. /* ** | RGB meta | */
  909. /* ** | plane | */
  910. /* ** -------------------- */
  911. /************************************************/
  912. layout->plane_addr[0] = base_addr + layout->plane_size[2];
  913. layout->plane_addr[1] = 0;
  914. if (!meta)
  915. goto done;
  916. layout->plane_addr[2] = base_addr;
  917. layout->plane_addr[3] = 0;
  918. }
  919. done:
  920. return 0;
  921. }
  922. static int _sde_format_populate_addrs_linear(
  923. struct msm_gem_address_space *aspace,
  924. struct drm_framebuffer *fb,
  925. struct sde_hw_fmt_layout *layout)
  926. {
  927. unsigned int i;
  928. /* Can now check the pitches given vs pitches expected */
  929. for (i = 0; i < layout->num_planes; ++i) {
  930. if (layout->plane_pitch[i] > fb->pitches[i]) {
  931. DRM_ERROR("plane %u expected pitch %u, fb %u\n",
  932. i, layout->plane_pitch[i], fb->pitches[i]);
  933. return -EINVAL;
  934. }
  935. }
  936. /* Populate addresses for simple formats here */
  937. for (i = 0; i < layout->num_planes; ++i) {
  938. if (aspace)
  939. layout->plane_addr[i] =
  940. msm_framebuffer_iova(fb, aspace, i);
  941. else
  942. layout->plane_addr[i] = msm_framebuffer_phys(fb, i);
  943. if (!layout->plane_addr[i]) {
  944. DRM_ERROR("failed to retrieve base addr\n");
  945. return -EFAULT;
  946. }
  947. }
  948. return 0;
  949. }
  950. int sde_format_populate_layout(
  951. struct msm_gem_address_space *aspace,
  952. struct drm_framebuffer *fb,
  953. struct sde_hw_fmt_layout *layout)
  954. {
  955. uint32_t plane_addr[SDE_MAX_PLANES];
  956. int i, ret;
  957. if (!fb || !layout) {
  958. DRM_ERROR("invalid arguments\n");
  959. return -EINVAL;
  960. }
  961. if ((fb->width > SDE_MAX_IMG_WIDTH) ||
  962. (fb->height > SDE_MAX_IMG_HEIGHT)) {
  963. DRM_ERROR("image dimensions outside max range\n");
  964. return -ERANGE;
  965. }
  966. layout->format = to_sde_format(msm_framebuffer_format(fb));
  967. /* Populate the plane sizes etc via get_format */
  968. ret = sde_format_get_plane_sizes(layout->format, fb->width, fb->height,
  969. layout, fb->pitches);
  970. if (ret)
  971. return ret;
  972. for (i = 0; i < SDE_MAX_PLANES; ++i)
  973. plane_addr[i] = layout->plane_addr[i];
  974. /* Populate the addresses given the fb */
  975. if (SDE_FORMAT_IS_UBWC(layout->format) ||
  976. SDE_FORMAT_IS_TILE(layout->format))
  977. ret = _sde_format_populate_addrs_ubwc(aspace, fb, layout);
  978. else
  979. ret = _sde_format_populate_addrs_linear(aspace, fb, layout);
  980. /* check if anything changed */
  981. if (!ret && !memcmp(plane_addr, layout->plane_addr, sizeof(plane_addr)))
  982. ret = -EAGAIN;
  983. return ret;
  984. }
  985. static void _sde_format_calc_offset_linear(struct sde_hw_fmt_layout *source,
  986. u32 x, u32 y)
  987. {
  988. if ((x == 0) && (y == 0))
  989. return;
  990. source->plane_addr[0] += y * source->plane_pitch[0];
  991. if (source->num_planes == 1) {
  992. source->plane_addr[0] += x * source->format->bpp;
  993. } else {
  994. uint32_t xoff, yoff;
  995. uint32_t v_subsample = 1;
  996. uint32_t h_subsample = 1;
  997. _sde_get_v_h_subsample_rate(source->format->chroma_sample,
  998. &v_subsample, &h_subsample);
  999. xoff = x / h_subsample;
  1000. yoff = y / v_subsample;
  1001. source->plane_addr[0] += x;
  1002. source->plane_addr[1] += xoff +
  1003. (yoff * source->plane_pitch[1]);
  1004. if (source->num_planes == 2) /* pseudo planar */
  1005. source->plane_addr[1] += xoff;
  1006. else /* planar */
  1007. source->plane_addr[2] += xoff +
  1008. (yoff * source->plane_pitch[2]);
  1009. }
  1010. }
  1011. int sde_format_populate_layout_with_roi(
  1012. struct msm_gem_address_space *aspace,
  1013. struct drm_framebuffer *fb,
  1014. struct sde_rect *roi,
  1015. struct sde_hw_fmt_layout *layout)
  1016. {
  1017. int ret;
  1018. ret = sde_format_populate_layout(aspace, fb, layout);
  1019. if (ret || !roi)
  1020. return ret;
  1021. if (!roi->w || !roi->h || (roi->x + roi->w > fb->width) ||
  1022. (roi->y + roi->h > fb->height)) {
  1023. DRM_ERROR("invalid roi=[%d,%d,%d,%d], fb=[%u,%u]\n",
  1024. roi->x, roi->y, roi->w, roi->h,
  1025. fb->width, fb->height);
  1026. ret = -EINVAL;
  1027. } else if (SDE_FORMAT_IS_LINEAR(layout->format)) {
  1028. _sde_format_calc_offset_linear(layout, roi->x, roi->y);
  1029. layout->width = roi->w;
  1030. layout->height = roi->h;
  1031. } else if (roi->x || roi->y || (roi->w != fb->width) ||
  1032. (roi->h != fb->height)) {
  1033. DRM_ERROR("non-linear layout with roi not supported\n");
  1034. ret = -EINVAL;
  1035. }
  1036. return ret;
  1037. }
  1038. int sde_format_check_modified_format(
  1039. const struct msm_kms *kms,
  1040. const struct msm_format *msm_fmt,
  1041. const struct drm_mode_fb_cmd2 *cmd,
  1042. struct drm_gem_object **bos)
  1043. {
  1044. const struct drm_format_info *info;
  1045. const struct sde_format *fmt;
  1046. struct sde_hw_fmt_layout layout;
  1047. uint32_t bos_total_size = 0;
  1048. int ret, i;
  1049. if (!msm_fmt || !cmd || !bos) {
  1050. DRM_ERROR("invalid arguments\n");
  1051. return -EINVAL;
  1052. }
  1053. fmt = to_sde_format(msm_fmt);
  1054. info = drm_format_info(fmt->base.pixel_format);
  1055. if (!info)
  1056. return -EINVAL;
  1057. ret = sde_format_get_plane_sizes(fmt, cmd->width, cmd->height,
  1058. &layout, cmd->pitches);
  1059. if (ret)
  1060. return ret;
  1061. for (i = 0; i < info->num_planes; i++) {
  1062. if (!bos[i]) {
  1063. DRM_ERROR("invalid handle for plane %d\n", i);
  1064. return -EINVAL;
  1065. }
  1066. if ((i == 0) || (bos[i] != bos[0]))
  1067. bos_total_size += bos[i]->size;
  1068. }
  1069. if (bos_total_size < layout.total_size) {
  1070. DRM_ERROR("buffers total size too small %u expected %u\n",
  1071. bos_total_size, layout.total_size);
  1072. return -EINVAL;
  1073. }
  1074. return 0;
  1075. }
  1076. const struct sde_format *sde_get_sde_format_ext(
  1077. const uint32_t format,
  1078. const uint64_t modifier)
  1079. {
  1080. uint32_t i = 0;
  1081. const struct sde_format *fmt = NULL;
  1082. const struct sde_format *map = NULL;
  1083. ssize_t map_size = 0;
  1084. /*
  1085. * Currently only support exactly zero or one modifier.
  1086. * All planes use the same modifier.
  1087. */
  1088. SDE_DEBUG("plane format modifier 0x%llX\n", modifier);
  1089. switch (modifier) {
  1090. case 0:
  1091. map = sde_format_map;
  1092. map_size = ARRAY_SIZE(sde_format_map);
  1093. break;
  1094. case DRM_FORMAT_MOD_QCOM_ALPHA_SWAP:
  1095. map = sde_format_map_alpha_swap;
  1096. map_size = ARRAY_SIZE(sde_format_map_alpha_swap);
  1097. break;
  1098. case DRM_FORMAT_MOD_QCOM_COMPRESSED:
  1099. case DRM_FORMAT_MOD_QCOM_COMPRESSED | DRM_FORMAT_MOD_QCOM_TILE:
  1100. map = sde_format_map_ubwc;
  1101. map_size = ARRAY_SIZE(sde_format_map_ubwc);
  1102. SDE_DEBUG("found fmt: %4.4s DRM_FORMAT_MOD_QCOM_COMPRESSED\n",
  1103. (char *)&format);
  1104. break;
  1105. case DRM_FORMAT_MOD_QCOM_DX:
  1106. map = sde_format_map_p010;
  1107. map_size = ARRAY_SIZE(sde_format_map_p010);
  1108. SDE_DEBUG("found fmt: %4.4s DRM_FORMAT_MOD_QCOM_DX\n",
  1109. (char *)&format);
  1110. break;
  1111. case (DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_COMPRESSED):
  1112. case (DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_COMPRESSED |
  1113. DRM_FORMAT_MOD_QCOM_TILE):
  1114. map = sde_format_map_p010_ubwc;
  1115. map_size = ARRAY_SIZE(sde_format_map_p010_ubwc);
  1116. SDE_DEBUG(
  1117. "found fmt: %4.4s DRM_FORMAT_MOD_QCOM_COMPRESSED/DX\n",
  1118. (char *)&format);
  1119. break;
  1120. case (DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_COMPRESSED |
  1121. DRM_FORMAT_MOD_QCOM_TIGHT):
  1122. case (DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_COMPRESSED |
  1123. DRM_FORMAT_MOD_QCOM_TIGHT | DRM_FORMAT_MOD_QCOM_TILE):
  1124. map = sde_format_map_tp10_ubwc;
  1125. map_size = ARRAY_SIZE(sde_format_map_tp10_ubwc);
  1126. SDE_DEBUG(
  1127. "found fmt: %4.4s DRM_FORMAT_MOD_QCOM_COMPRESSED/DX/TIGHT\n",
  1128. (char *)&format);
  1129. break;
  1130. case DRM_FORMAT_MOD_QCOM_TILE:
  1131. map = sde_format_map_tile;
  1132. map_size = ARRAY_SIZE(sde_format_map_tile);
  1133. SDE_DEBUG("found fmt: %4.4s DRM_FORMAT_MOD_QCOM_TILE\n",
  1134. (char *)&format);
  1135. break;
  1136. case (DRM_FORMAT_MOD_QCOM_TILE | DRM_FORMAT_MOD_QCOM_DX):
  1137. map = sde_format_map_p010_tile;
  1138. map_size = ARRAY_SIZE(sde_format_map_p010_tile);
  1139. SDE_DEBUG("found fmt: %4.4s DRM_FORMAT_MOD_QCOM_TILE/DX\n",
  1140. (char *)&format);
  1141. break;
  1142. case (DRM_FORMAT_MOD_QCOM_TILE | DRM_FORMAT_MOD_QCOM_DX |
  1143. DRM_FORMAT_MOD_QCOM_TIGHT):
  1144. map = sde_format_map_tp10_tile;
  1145. map_size = ARRAY_SIZE(sde_format_map_tp10_tile);
  1146. SDE_DEBUG(
  1147. "found fmt: %4.4s DRM_FORMAT_MOD_QCOM_TILE/DX/TIGHT\n",
  1148. (char *)&format);
  1149. break;
  1150. default:
  1151. SDE_ERROR("unsupported format modifier %llX\n", modifier);
  1152. return NULL;
  1153. }
  1154. for (i = 0; i < map_size; i++) {
  1155. if (format == map[i].base.pixel_format) {
  1156. fmt = &map[i];
  1157. break;
  1158. }
  1159. }
  1160. if (fmt == NULL)
  1161. SDE_ERROR("unsupported fmt: %4.4s modifier 0x%llX\n",
  1162. (char *)&format, modifier);
  1163. else
  1164. SDE_DEBUG("fmt %4.4s mod 0x%llX ubwc %d yuv %d\n",
  1165. (char *)&format, modifier,
  1166. SDE_FORMAT_IS_UBWC(fmt),
  1167. SDE_FORMAT_IS_YUV(fmt));
  1168. return fmt;
  1169. }
  1170. const struct msm_format *sde_get_msm_format(
  1171. struct msm_kms *kms,
  1172. const uint32_t format,
  1173. const uint64_t modifier)
  1174. {
  1175. const struct sde_format *fmt = sde_get_sde_format_ext(format,
  1176. modifier);
  1177. if (fmt)
  1178. return &fmt->base;
  1179. return NULL;
  1180. }
  1181. uint32_t sde_populate_formats(
  1182. const struct sde_format_extended *format_list,
  1183. uint32_t *pixel_formats,
  1184. uint64_t *pixel_modifiers,
  1185. uint32_t pixel_formats_max)
  1186. {
  1187. uint32_t i, fourcc_format;
  1188. if (!format_list || !pixel_formats)
  1189. return 0;
  1190. for (i = 0, fourcc_format = 0;
  1191. format_list->fourcc_format && i < pixel_formats_max;
  1192. ++format_list) {
  1193. /* verify if listed format is in sde_format_map? */
  1194. /* optionally return modified formats */
  1195. if (pixel_modifiers) {
  1196. /* assume same modifier for all fb planes */
  1197. pixel_formats[i] = format_list->fourcc_format;
  1198. pixel_modifiers[i++] = format_list->modifier;
  1199. } else {
  1200. /* assume base formats grouped together */
  1201. if (fourcc_format != format_list->fourcc_format) {
  1202. fourcc_format = format_list->fourcc_format;
  1203. pixel_formats[i++] = fourcc_format;
  1204. }
  1205. }
  1206. }
  1207. return i;
  1208. }
  1209. int sde_format_validate_fmt(struct msm_kms *kms,
  1210. const struct sde_format *sde_fmt,
  1211. const struct sde_format_extended *fmt_list)
  1212. {
  1213. const struct sde_format *fmt_tmp;
  1214. bool valid_format = false;
  1215. int ret = 0;
  1216. if (!sde_fmt || !fmt_list) {
  1217. SDE_ERROR("invalid fmt:%d list:%d\n",
  1218. !sde_fmt, !fmt_list);
  1219. ret = -EINVAL;
  1220. goto exit;
  1221. }
  1222. while (fmt_list->fourcc_format) {
  1223. fmt_tmp = sde_get_sde_format_ext(fmt_list->fourcc_format,
  1224. fmt_list->modifier);
  1225. if (fmt_tmp
  1226. && (fmt_tmp->base.pixel_format == sde_fmt->base.pixel_format)
  1227. && (fmt_tmp->fetch_mode == sde_fmt->fetch_mode)) {
  1228. valid_format = true;
  1229. break;
  1230. }
  1231. ++fmt_list;
  1232. }
  1233. if (!valid_format) {
  1234. SDE_ERROR("fmt:%d mode:%d not found within the list!\n",
  1235. sde_fmt->base.pixel_format, sde_fmt->fetch_mode);
  1236. ret = -EINVAL;
  1237. }
  1238. exit:
  1239. return ret;
  1240. }