77
88#include "iomfb_internal.h"
99
10+ #include "iomfb_plane.h"
11+ #include "linux/printk.h"
12+ #include "vdso/align.h"
1013#include <drm/drm_atomic.h>
1114#include <drm/drm_atomic_helper.h>
1215#include <drm/drm_fourcc.h>
1619#include <drm/drm_gem_dma_helper.h>
1720#include <drm/drm_plane.h>
1821
22+ #ifndef DRM_FORMAT_MOD_APPLE_INTERCHANGE_COMPRESSED
23+ #define DRM_FORMAT_MOD_APPLE_INTERCHANGE_COMPRESSED fourcc_mod_code(APPLE, 3)
24+ #endif
25+
1926#define FRAC_16_16 (mult , div ) (((mult) << 16) / (div))
2027
2128static int apple_plane_atomic_check (struct drm_plane * plane ,
@@ -248,7 +255,6 @@ static void apple_plane_atomic_update(struct drm_plane *plane,
248255 .stride = fb -> pitches [0 ],
249256 .width = fb -> width ,
250257 .height = fb -> height ,
251- .buf_size = fb -> height * fb -> pitches [0 ],
252258 // .surface_id = req->swap.surf_ids[l],
253259
254260 /* Only used for compressed or multiplanar surfaces */
@@ -257,8 +263,12 @@ static void apple_plane_atomic_update(struct drm_plane *plane,
257263 .pel_h = 1 ,
258264 .has_comp = 1 ,
259265 .has_planes = 1 ,
266+ .has_compr_info = 1 ,
260267 };
261268
269+ BUILD_BUG_ON (sizeof (struct dcp_plane_info ) != 0x50 );
270+ BUILD_BUG_ON (sizeof (struct dcp_compression_info ) != 0x34 );
271+
262272 /* Populate plane information for planar formats */
263273 struct dcp_surface * surf = & new_state -> surf ;
264274 for (int i = 0 ; fb -> format -> num_planes && i < fb -> format -> num_planes ; i ++ ) {
@@ -279,8 +289,36 @@ static void apple_plane_atomic_update(struct drm_plane *plane,
279289 .tile_h = bh ,
280290 };
281291
282- if (i > 0 )
283- surf -> buf_size += surf -> planes [i ].size ;
292+ if (fb -> modifier == DRM_FORMAT_MOD_APPLE_INTERCHANGE_COMPRESSED ) {
293+ u32 tw = ALIGN (width , 16 ) / 16 ;
294+ u32 th = ALIGN (height , 16 ) / 16 ;
295+ u32 tsize_B = 16 * 16 * 4 ;
296+
297+ u32 meta_offset = ALIGN (tw * th * tsize_B , 128 );
298+ u32 meta_size = roundup_pow_of_two (width ) * roundup_pow_of_two (height ) * 8 ;
299+
300+ surf -> planes [i ].tile_w = 16 ;
301+ surf -> planes [i ].tile_h = 16 ;
302+ surf -> planes [i ].stride = tw * tsize_B ;
303+ surf -> planes [i ].size = meta_offset + meta_size ;
304+ surf -> planes [i ].tile_size = tsize_B ;
305+ surf -> planes [i ].address_format = 5 ; // interchange tiles
306+
307+ surf -> compression_info [i ] = (struct dcp_compression_info ) {
308+ .tile_w = 16 ,
309+ .tile_h = 16 ,
310+ .data_offset = 0 ,
311+ .meta_offset = meta_offset ,
312+ .tile_meta_bytes = 8 ,
313+ .tiles_w = tw ,
314+ .tiles_h = th ,
315+ .tile_bytes = tsize_B ,
316+ .row_stride = tw * tsize_B ,
317+ .compresson_type = 3 , // interchange compression
318+ };
319+ }
320+
321+ surf -> buf_size += surf -> planes [i ].size ;
284322 }
285323
286324 /* the obvious helper call drm_fb_dma_get_gem_addr() adjusts
@@ -426,6 +464,7 @@ static const u32 dcp_overlay_formats_12_x[] = {
426464};
427465
428466u64 apple_format_modifiers [] = {
467+ DRM_FORMAT_MOD_APPLE_INTERCHANGE_COMPRESSED ,
429468 DRM_FORMAT_MOD_LINEAR ,
430469 DRM_FORMAT_MOD_INVALID
431470};
0 commit comments