Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions drivers/gpu/drm/apple/iomfb_plane.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,26 @@ struct dcp_plane_info {
u16 tile_size;
u8 tile_w;
u8 tile_h;
u32 unk[13];
u8 unk1[0xd];
u8 address_format;
u8 unk2[0x26];
} __packed;

struct dcp_compression_info {
u32 tile_w;
u32 tile_h;
u32 meta_offset;
u32 data_offset;
u32 tile_meta_bytes;
u32 tiles_w;
u32 tiles_h;
u32 unk1;
u32 compresson_type;
u32 unk3;
u8 _pad1[3];
u32 tile_bytes;
u32 row_stride;
u8 pad2;
} __packed;

struct dcp_component_types {
Expand Down Expand Up @@ -100,7 +119,7 @@ struct dcp_surface {
u64 has_comp;
struct dcp_plane_info planes[DCP_SURF_MAX_PLANES];
u64 has_planes;
u32 compression_info[DCP_SURF_MAX_PLANES][13];
struct dcp_compression_info compression_info[DCP_SURF_MAX_PLANES];
u64 has_compr_info;
u32 unk_num;
u32 unk_denom;
Expand Down
45 changes: 42 additions & 3 deletions drivers/gpu/drm/apple/plane.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

#include "iomfb_internal.h"

#include "iomfb_plane.h"
#include "linux/printk.h"
#include "vdso/align.h"
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_fourcc.h>
Expand All @@ -16,6 +19,10 @@
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_plane.h>

#ifndef DRM_FORMAT_MOD_APPLE_INTERCHANGE_COMPRESSED
#define DRM_FORMAT_MOD_APPLE_INTERCHANGE_COMPRESSED fourcc_mod_code(APPLE, 3)
#endif

#define FRAC_16_16(mult, div) (((mult) << 16) / (div))

static int apple_plane_atomic_check(struct drm_plane *plane,
Expand Down Expand Up @@ -248,7 +255,6 @@ static void apple_plane_atomic_update(struct drm_plane *plane,
.stride = fb->pitches[0],
.width = fb->width,
.height = fb->height,
.buf_size = fb->height * fb->pitches[0],
// .surface_id = req->swap.surf_ids[l],

/* Only used for compressed or multiplanar surfaces */
Expand All @@ -257,8 +263,12 @@ static void apple_plane_atomic_update(struct drm_plane *plane,
.pel_h = 1,
.has_comp = 1,
.has_planes = 1,
.has_compr_info = 1,
};

BUILD_BUG_ON(sizeof(struct dcp_plane_info) != 0x50);
BUILD_BUG_ON(sizeof(struct dcp_compression_info) != 0x34);

/* Populate plane information for planar formats */
struct dcp_surface *surf = &new_state->surf;
for (int i = 0; fb->format->num_planes && i < fb->format->num_planes; i++) {
Expand All @@ -279,8 +289,36 @@ static void apple_plane_atomic_update(struct drm_plane *plane,
.tile_h = bh,
};

if (i > 0)
surf->buf_size += surf->planes[i].size;
if (fb->modifier == DRM_FORMAT_MOD_APPLE_INTERCHANGE_COMPRESSED) {
u32 tw = ALIGN(width, 16) / 16;
u32 th = ALIGN(height, 16) / 16;
u32 tsize_B = 16 * 16 * 4;

u32 meta_offset = ALIGN(tw * th * tsize_B, 128);
u32 meta_size = roundup_pow_of_two(width) * roundup_pow_of_two(height) * 8;

surf->planes[i].tile_w = 16;
surf->planes[i].tile_h = 16;
surf->planes[i].stride = tw * tsize_B;
surf->planes[i].size = meta_offset + meta_size;
surf->planes[i].tile_size = tsize_B;
surf->planes[i].address_format = 5; // interchange tiles

surf->compression_info[i] = (struct dcp_compression_info) {
.tile_w = 16,
.tile_h = 16,
.data_offset = 0,
.meta_offset = meta_offset,
.tile_meta_bytes = 8,
.tiles_w = tw,
.tiles_h = th,
.tile_bytes = tsize_B,
.row_stride = tw * tsize_B,
.compresson_type = 3, // interchange compression
};
}

surf->buf_size += surf->planes[i].size;
}

/* the obvious helper call drm_fb_dma_get_gem_addr() adjusts
Expand Down Expand Up @@ -426,6 +464,7 @@ static const u32 dcp_overlay_formats_12_x[] = {
};

u64 apple_format_modifiers[] = {
DRM_FORMAT_MOD_APPLE_INTERCHANGE_COMPRESSED,
DRM_FORMAT_MOD_LINEAR,
DRM_FORMAT_MOD_INVALID
};
Expand Down