Merge "disp: msm: sde: frame data feature"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
1d8a30b659
@@ -526,6 +526,92 @@ struct sde_drm_roi_v1 {
|
||||
#define SDE_RECOVERY_CAPTURE 1
|
||||
#define SDE_RECOVERY_HARD_RESET 2
|
||||
|
||||
/**
|
||||
* Define UBWC statistics config
|
||||
*/
|
||||
#define UBWC_STATS_MAX_ROI 0x3
|
||||
|
||||
/**
|
||||
* struct sde_drm_ubwc_stats_roi - region of interest for ubwc stats
|
||||
* y_coord0: first y offset from top of display
|
||||
* y_coord1: second y offset from top of display
|
||||
*/
|
||||
struct sde_drm_ubwc_stats_roi {
|
||||
__u16 y_coord0;
|
||||
__u16 y_coord1;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sde_drm_ubwc_stats_data: ubwc statistics
|
||||
* roi: region of interest
|
||||
* worst_bw: worst bandwidth, per roi
|
||||
* worst_bw_y_coord: y offset (row) location of worst bandwidth, per roi
|
||||
* total_bw: total bandwidth, per roi
|
||||
* error: error status
|
||||
* meta_error: meta error data
|
||||
*/
|
||||
struct sde_drm_ubwc_stats_data {
|
||||
struct sde_drm_ubwc_stats_roi roi;
|
||||
__u16 worst_bw[UBWC_STATS_MAX_ROI];
|
||||
__u16 worst_bw_y_coord[UBWC_STATS_MAX_ROI];
|
||||
__u32 total_bw[UBWC_STATS_MAX_ROI];
|
||||
__u32 error;
|
||||
__u32 meta_error;
|
||||
};
|
||||
|
||||
/**
|
||||
* Define frame data config
|
||||
*/
|
||||
#define SDE_FRAME_DATA_BUFFER_MAX 0x3
|
||||
#define SDE_FRAME_DATA_GUARD_BYTES 0xFF
|
||||
#define SDE_FRAME_DATA_MAX_PLANES 0x10
|
||||
|
||||
/**
|
||||
* struct sde_drm_frame_data_buffers_ctrl - control frame data buffers
|
||||
* num_buffers: number of allocated buffers
|
||||
* fds: fd list for allocated buffers
|
||||
*/
|
||||
struct sde_drm_frame_data_buffers_ctrl {
|
||||
__u32 num_buffers;
|
||||
__u32 fds[SDE_FRAME_DATA_BUFFER_MAX];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sde_drm_frame_data_buf - frame data buffer info sent to userspace
|
||||
* fd: buffer fd
|
||||
* offset: offset from buffer address
|
||||
* status: status flag
|
||||
*/
|
||||
struct sde_drm_frame_data_buf {
|
||||
__u32 fd;
|
||||
__u32 offset;
|
||||
__u32 status;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sde_drm_plane_frame_data - definition of plane frame data struct
|
||||
* plane_id: drm plane id
|
||||
* ubwc_stats: ubwc statistics
|
||||
*/
|
||||
struct sde_drm_plane_frame_data {
|
||||
__u32 plane_id;
|
||||
|
||||
struct sde_drm_ubwc_stats_data ubwc_stats;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sde_drm_frame_data_packet - definition of frame data struct
|
||||
* frame_count: interface frame count
|
||||
* commit_count: sw commit count
|
||||
* plane_frame_data: data available per plane
|
||||
*/
|
||||
struct sde_drm_frame_data_packet {
|
||||
__u32 frame_count;
|
||||
__u64 commit_count;
|
||||
|
||||
struct sde_drm_plane_frame_data plane_frame_data[SDE_FRAME_DATA_MAX_PLANES];
|
||||
};
|
||||
|
||||
/*
|
||||
* Colorimetry Data Block values
|
||||
* These bit nums are defined as per the CTA spec
|
||||
@@ -723,6 +809,7 @@ struct drm_msm_noise_layer_cfg {
|
||||
#define DRM_EVENT_LTM_WB_PB 0X80000009
|
||||
#define DRM_EVENT_LTM_OFF 0X8000000A
|
||||
#define DRM_EVENT_MMRM_CB 0X8000000B
|
||||
#define DRM_EVENT_FRAME_DATA 0x8000000C
|
||||
|
||||
#ifndef DRM_MODE_FLAG_VID_MODE_PANEL
|
||||
#define DRM_MODE_FLAG_VID_MODE_PANEL 0x01
|
||||
|
@@ -136,6 +136,7 @@ enum msm_mdp_plane_property {
|
||||
PLANE_PROP_INVERSE_PMA,
|
||||
PLANE_PROP_FP16_IGC,
|
||||
PLANE_PROP_FP16_UNMULT,
|
||||
PLANE_PROP_UBWC_STATS_ROI,
|
||||
|
||||
/* enum/bitmask properties */
|
||||
PLANE_PROP_BLEND_OP,
|
||||
@@ -181,6 +182,7 @@ enum msm_mdp_crtc_property {
|
||||
CRTC_PROP_CACHE_STATE,
|
||||
CRTC_PROP_VM_REQ_STATE,
|
||||
CRTC_PROP_NOISE_LAYER_V1,
|
||||
CRTC_PROP_FRAME_DATA_BUF,
|
||||
|
||||
/* total # of properties */
|
||||
CRTC_PROP_COUNT
|
||||
|
@@ -28,6 +28,9 @@
|
||||
#include "msm_mmu.h"
|
||||
#include "sde_dbg.h"
|
||||
|
||||
#define GUARD_BYTES (BIT(8) - 1)
|
||||
#define ALIGNED_OFFSET (U32_MAX & ~(GUARD_BYTES))
|
||||
|
||||
static void msm_gem_vunmap_locked(struct drm_gem_object *obj);
|
||||
|
||||
|
||||
@@ -1395,3 +1398,72 @@ void msm_gem_object_set_name(struct drm_gem_object *bo, const char *fmt, ...)
|
||||
vsnprintf(msm_obj->name, sizeof(msm_obj->name), fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void msm_gem_put_buffer(struct drm_gem_object *gem)
|
||||
{
|
||||
struct msm_gem_object *msm_gem;
|
||||
|
||||
if (!gem)
|
||||
return;
|
||||
|
||||
msm_gem = to_msm_bo(gem);
|
||||
|
||||
msm_gem_put_iova(gem, msm_gem->aspace);
|
||||
msm_gem_put_vaddr(gem);
|
||||
}
|
||||
|
||||
int msm_gem_get_buffer(struct drm_gem_object *gem,
|
||||
struct drm_device *dev, struct drm_framebuffer *fb,
|
||||
uint32_t align_size)
|
||||
{
|
||||
struct msm_gem_object *msm_gem;
|
||||
uint32_t size;
|
||||
uint64_t iova_aligned;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (!gem) {
|
||||
DRM_ERROR("invalid drm gem");
|
||||
return ret;
|
||||
}
|
||||
|
||||
msm_gem = to_msm_bo(gem);
|
||||
|
||||
size = PAGE_ALIGN(gem->size);
|
||||
if (size < (align_size + GUARD_BYTES)) {
|
||||
DRM_ERROR("invalid gem size");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
msm_gem_smmu_address_space_get(dev, MSM_SMMU_DOMAIN_UNSECURE);
|
||||
|
||||
if (PTR_ERR(msm_gem->aspace) == -ENODEV) {
|
||||
DRM_DEBUG("IOMMU not present, relying on VRAM.");
|
||||
} else if (IS_ERR_OR_NULL(msm_gem->aspace)) {
|
||||
ret = PTR_ERR(msm_gem->aspace);
|
||||
DRM_ERROR("failed to get aspace");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = msm_gem_get_iova(gem, msm_gem->aspace, &msm_gem->iova);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to get the iova ret %d", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
msm_gem_get_vaddr(gem);
|
||||
if (IS_ERR_OR_NULL(msm_gem->vaddr)) {
|
||||
DRM_ERROR("failed to get vaddr");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
iova_aligned = (msm_gem->iova + GUARD_BYTES) & ALIGNED_OFFSET;
|
||||
msm_gem->offset = iova_aligned - msm_gem->iova;
|
||||
msm_gem->iova = msm_gem->iova + msm_gem->offset;
|
||||
|
||||
return 0;
|
||||
|
||||
exit:
|
||||
msm_gem_put_buffer(gem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -146,6 +146,10 @@ struct msm_gem_object {
|
||||
* new pagetables due to cb switch
|
||||
*/
|
||||
bool obj_dirty;
|
||||
|
||||
/* iova address and aligned offset */
|
||||
uint64_t iova;
|
||||
uint32_t offset;
|
||||
};
|
||||
#define to_msm_bo(x) container_of(x, struct msm_gem_object, base)
|
||||
|
||||
@@ -219,4 +223,21 @@ struct msm_gem_submit {
|
||||
} bos[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* msm_gem_put_buffer - put gem buffer
|
||||
* @gem: pointer to gem buffer object
|
||||
*/
|
||||
void msm_gem_put_buffer(struct drm_gem_object *gem);
|
||||
|
||||
/**
|
||||
* msm_gem_gem_buffer - get a gem buffer
|
||||
* @gem: drm gem object
|
||||
* @drm_device: pointer to drm device
|
||||
* @fb: frame buffer object
|
||||
* @align_size: size to align the buffer to
|
||||
*/
|
||||
int msm_gem_get_buffer(struct drm_gem_object *gem,
|
||||
struct drm_device *dev, struct drm_framebuffer *fb,
|
||||
uint32_t align_size);
|
||||
|
||||
#endif /* __MSM_GEM_H__ */
|
||||
|
@@ -454,6 +454,23 @@ static const struct attribute_group *sde_crtc_attr_groups[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static void sde_crtc_event_notify(struct drm_crtc *crtc, uint32_t type, uint32_t len, uint64_t val)
|
||||
{
|
||||
struct drm_event event;
|
||||
|
||||
if (!crtc) {
|
||||
SDE_ERROR("invalid crtc\n");
|
||||
return;
|
||||
}
|
||||
|
||||
event.type = type;
|
||||
event.length = len;
|
||||
msm_mode_object_event_notify(&crtc->base, crtc->dev, &event, (u8 *)&val);
|
||||
|
||||
SDE_EVT32(DRMID(crtc), type, len, val >> 32, val & 0xFFFFFFFF);
|
||||
SDE_DEBUG("crtc:%d event(%d) value(%llu) notified\n", DRMID(crtc), type, val);
|
||||
}
|
||||
|
||||
static void sde_crtc_destroy(struct drm_crtc *crtc)
|
||||
{
|
||||
struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
|
||||
@@ -2313,6 +2330,144 @@ static void _sde_crtc_dest_scaler_setup(struct drm_crtc *crtc)
|
||||
}
|
||||
}
|
||||
|
||||
static void _sde_crtc_put_frame_data_buffer(struct sde_frame_data_buffer *buf)
|
||||
{
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
msm_gem_put_buffer(buf->gem);
|
||||
kfree(buf);
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
static int _sde_crtc_get_frame_data_buffer(struct drm_crtc *crtc, uint32_t fd)
|
||||
{
|
||||
struct sde_crtc *sde_crtc;
|
||||
struct sde_frame_data_buffer *buf;
|
||||
uint32_t cur_buf;
|
||||
|
||||
sde_crtc = to_sde_crtc(crtc);
|
||||
cur_buf = sde_crtc->frame_data.cnt;
|
||||
|
||||
buf = kzalloc(sizeof(struct sde_frame_data_buffer), GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
sde_crtc->frame_data.buf[cur_buf] = buf;
|
||||
buf->fb = drm_framebuffer_lookup(crtc->dev, NULL, fd);
|
||||
if (!buf->fb) {
|
||||
SDE_ERROR("unable to get fb");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buf->gem = msm_framebuffer_bo(buf->fb, 0);
|
||||
if (!buf->gem) {
|
||||
SDE_ERROR("unable to get drm gem");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return msm_gem_get_buffer(buf->gem, crtc->dev, buf->fb,
|
||||
sizeof(struct sde_drm_frame_data_packet));
|
||||
}
|
||||
|
||||
static void _sde_crtc_set_frame_data_buffers(struct drm_crtc *crtc,
|
||||
struct sde_crtc_state *cstate, void __user *usr)
|
||||
{
|
||||
struct sde_crtc *sde_crtc;
|
||||
struct sde_drm_frame_data_buffers_ctrl ctrl;
|
||||
int i, ret;
|
||||
|
||||
if (!crtc || !cstate || !usr)
|
||||
return;
|
||||
|
||||
sde_crtc = to_sde_crtc(crtc);
|
||||
|
||||
ret = copy_from_user(&ctrl, usr, sizeof(ctrl));
|
||||
if (ret) {
|
||||
SDE_ERROR("failed to copy frame data ctrl, ret %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ctrl.num_buffers) {
|
||||
SDE_DEBUG("clearing frame data buffers");
|
||||
goto exit;
|
||||
} else if (ctrl.num_buffers > SDE_FRAME_DATA_BUFFER_MAX) {
|
||||
SDE_ERROR("invalid number of buffers %d", ctrl.num_buffers);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ctrl.num_buffers; i++) {
|
||||
if (_sde_crtc_get_frame_data_buffer(crtc, ctrl.fds[i])) {
|
||||
SDE_ERROR("unable to set buffer for fd %d", ctrl.fds[i]);
|
||||
goto exit;
|
||||
}
|
||||
sde_crtc->frame_data.cnt++;
|
||||
}
|
||||
|
||||
return;
|
||||
exit:
|
||||
while (sde_crtc->frame_data.cnt--)
|
||||
_sde_crtc_put_frame_data_buffer(
|
||||
sde_crtc->frame_data.buf[sde_crtc->frame_data.cnt]);
|
||||
}
|
||||
|
||||
static void _sde_crtc_frame_data_notify(struct drm_crtc *crtc,
|
||||
struct sde_drm_frame_data_packet *frame_data_packet)
|
||||
{
|
||||
struct sde_crtc *sde_crtc;
|
||||
struct sde_drm_frame_data_buf buf;
|
||||
struct msm_gem_object *msm_gem;
|
||||
u32 cur_buf;
|
||||
|
||||
sde_crtc = to_sde_crtc(crtc);
|
||||
cur_buf = sde_crtc->frame_data.idx;
|
||||
msm_gem = to_msm_bo(sde_crtc->frame_data.buf[cur_buf]->gem);
|
||||
|
||||
buf.fd = sde_crtc->frame_data.buf[cur_buf]->fd;
|
||||
buf.offset = msm_gem->offset;
|
||||
|
||||
sde_crtc_event_notify(crtc, DRM_EVENT_FRAME_DATA, sizeof(struct sde_drm_frame_data_buf),
|
||||
(uint64_t)(&buf));
|
||||
|
||||
sde_crtc->frame_data.idx = ++sde_crtc->frame_data.idx % sde_crtc->frame_data.cnt;
|
||||
}
|
||||
|
||||
void sde_crtc_get_frame_data(struct drm_crtc *crtc)
|
||||
{
|
||||
struct sde_crtc *sde_crtc;
|
||||
struct drm_plane *plane;
|
||||
struct sde_drm_frame_data_packet frame_data_packet = {0, 0};
|
||||
struct sde_drm_frame_data_packet *data;
|
||||
struct sde_frame_data *frame_data;
|
||||
int i = 0;
|
||||
|
||||
if (!crtc || !crtc->state)
|
||||
return;
|
||||
|
||||
sde_crtc = to_sde_crtc(crtc);
|
||||
frame_data = &sde_crtc->frame_data;
|
||||
|
||||
if (frame_data->cnt) {
|
||||
struct msm_gem_object *msm_gem;
|
||||
|
||||
msm_gem = to_msm_bo(frame_data->buf[frame_data->cnt]->gem);
|
||||
data = (struct sde_drm_frame_data_packet *)
|
||||
(((u8 *)msm_gem->vaddr) + msm_gem->offset);
|
||||
} else {
|
||||
data = &frame_data_packet;
|
||||
}
|
||||
|
||||
data->commit_count = sde_crtc->play_count;
|
||||
data->frame_count = sde_crtc->fps_info.frame_count;
|
||||
|
||||
/* Collect plane specific data */
|
||||
drm_for_each_plane_mask(plane, crtc->dev, sde_crtc->plane_mask_old)
|
||||
sde_plane_get_frame_data(plane, &data->plane_frame_data[i]);
|
||||
|
||||
if (frame_data->cnt)
|
||||
_sde_crtc_frame_data_notify(crtc, data);
|
||||
}
|
||||
|
||||
static void sde_crtc_frame_event_cb(void *data, u32 event, ktime_t ts)
|
||||
{
|
||||
struct drm_crtc *crtc = (struct drm_crtc *)data;
|
||||
@@ -2320,8 +2475,6 @@ static void sde_crtc_frame_event_cb(void *data, u32 event, ktime_t ts)
|
||||
struct msm_drm_private *priv;
|
||||
struct sde_crtc_frame_event *fevent;
|
||||
struct sde_kms_frame_event_cb_data *cb_data;
|
||||
struct drm_plane *plane;
|
||||
u32 ubwc_error, meta_error;
|
||||
unsigned long flags;
|
||||
u32 crtc_id;
|
||||
|
||||
@@ -2360,21 +2513,8 @@ static void sde_crtc_frame_event_cb(void *data, u32 event, ktime_t ts)
|
||||
/* log and clear plane ubwc errors if any */
|
||||
if (event & (SDE_ENCODER_FRAME_EVENT_ERROR
|
||||
| SDE_ENCODER_FRAME_EVENT_PANEL_DEAD
|
||||
| SDE_ENCODER_FRAME_EVENT_DONE)) {
|
||||
drm_for_each_plane_mask(plane, crtc->dev,
|
||||
sde_crtc->plane_mask_old) {
|
||||
ubwc_error = sde_plane_get_ubwc_error(plane);
|
||||
meta_error = sde_plane_get_meta_error(plane);
|
||||
if (ubwc_error | meta_error) {
|
||||
SDE_EVT32(DRMID(crtc), DRMID(plane), ubwc_error,
|
||||
meta_error, SDE_EVTLOG_ERROR);
|
||||
SDE_DEBUG("crtc%d plane %d ubwc_error %d meta_error %d\n",
|
||||
DRMID(crtc), DRMID(plane), ubwc_error, meta_error);
|
||||
sde_plane_clear_ubwc_error(plane);
|
||||
sde_plane_clear_meta_error(plane);
|
||||
}
|
||||
}
|
||||
}
|
||||
| SDE_ENCODER_FRAME_EVENT_DONE))
|
||||
sde_crtc_get_frame_data(crtc);
|
||||
|
||||
if ((event & SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE) &&
|
||||
(sde_crtc && sde_crtc->retire_frame_event_sf)) {
|
||||
@@ -2654,23 +2794,6 @@ static void sde_crtc_frame_event_work(struct kthread_work *work)
|
||||
SDE_ATRACE_END("crtc_frame_event");
|
||||
}
|
||||
|
||||
static void sde_crtc_event_notify(struct drm_crtc *crtc, uint32_t type, uint32_t len, uint32_t val)
|
||||
{
|
||||
struct drm_event event;
|
||||
|
||||
if (!crtc) {
|
||||
SDE_ERROR("invalid crtc\n");
|
||||
return;
|
||||
}
|
||||
|
||||
event.type = type;
|
||||
event.length = len;
|
||||
msm_mode_object_event_notify(&crtc->base, crtc->dev, &event, (u8 *)&val);
|
||||
|
||||
SDE_EVT32(DRMID(crtc), type, len, val);
|
||||
SDE_DEBUG("crtc:%d event(%d) value(%d) notified\n", DRMID(crtc), type, val);
|
||||
}
|
||||
|
||||
void sde_crtc_complete_commit(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *old_state)
|
||||
{
|
||||
@@ -5707,6 +5830,10 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc,
|
||||
|
||||
sde_crtc_install_noise_layer_properties(sde_crtc, catalog, info);
|
||||
|
||||
if (catalog->has_ubwc_stats)
|
||||
msm_property_install_range(&sde_crtc->property_info, "frame_data",
|
||||
0x0, 0, ~0, 0, CRTC_PROP_FRAME_DATA_BUF);
|
||||
|
||||
kfree(info);
|
||||
}
|
||||
|
||||
@@ -5862,6 +5989,9 @@ static int sde_crtc_atomic_set_property(struct drm_crtc *crtc,
|
||||
_sde_crtc_set_noise_layer(sde_crtc, cstate,
|
||||
(void __user *)(uintptr_t)val);
|
||||
break;
|
||||
case CRTC_PROP_FRAME_DATA_BUF:
|
||||
_sde_crtc_set_frame_data_buffers(crtc, cstate, (void __user *)(uintptr_t)val);
|
||||
break;
|
||||
default:
|
||||
/* nothing to do */
|
||||
break;
|
||||
|
@@ -224,6 +224,30 @@ struct sde_crtc_misr_info {
|
||||
*/
|
||||
#define SDE_CRTC_MAX_EVENT_COUNT 16
|
||||
|
||||
/**
|
||||
* struct sde_frame_data_buffer - defines frame data buffer structure
|
||||
* @fd: framebuffer id associated with this buffer
|
||||
* @fb: drm framebuffer for the buffer
|
||||
* @gem: drm gem handle for he buffer
|
||||
*/
|
||||
struct sde_frame_data_buffer {
|
||||
u32 fd;
|
||||
struct drm_framebuffer *fb;
|
||||
struct drm_gem_object *gem;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sde_frame_data - defines sde frame data structure
|
||||
* @idx : currently used frame data buffe
|
||||
* @cnt : rnumber of available frame data buffers
|
||||
* @buf : list of frame data buffers
|
||||
*/
|
||||
struct sde_frame_data {
|
||||
u32 idx;
|
||||
u32 cnt;
|
||||
struct sde_frame_data_buffer *buf[SDE_FRAME_DATA_BUFFER_MAX];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sde_crtc - virtualized CRTC data structure
|
||||
* @base : Base drm crtc structure
|
||||
@@ -303,6 +327,7 @@ struct sde_crtc_misr_info {
|
||||
* @skip_blend_plane_w: skip blend plane width
|
||||
* @skip_blend_plane_h: skip blend plane height
|
||||
* @line_time_in_ns : current mode line time in nano sec is needed for QOS update
|
||||
* @frame_data : Framedata data structure
|
||||
*/
|
||||
struct sde_crtc {
|
||||
struct drm_crtc base;
|
||||
@@ -402,6 +427,8 @@ struct sde_crtc {
|
||||
u32 skip_blend_plane_w;
|
||||
u32 skip_blend_plane_h;
|
||||
u32 line_time_in_ns;
|
||||
|
||||
struct sde_frame_data frame_data;
|
||||
};
|
||||
|
||||
enum sde_crtc_dirty_flags {
|
||||
|
@@ -1938,6 +1938,9 @@ static void sde_sspp_set_features(struct sde_mdss_cfg *sde_cfg,
|
||||
SSPP_MAX_PER_PIPE_BW_HIGH, i);
|
||||
else
|
||||
sblk->max_per_pipe_bw_high = sblk->max_per_pipe_bw;
|
||||
|
||||
if (sde_cfg->has_ubwc_stats)
|
||||
set_bit(SDE_SSPP_UBWC_STATS, &sspp->features);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5072,6 +5075,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
|
||||
sde_cfg->has_precise_vsync_ts = true;
|
||||
sde_cfg->has_avr_step = true;
|
||||
sde_cfg->has_trusted_vm_support = true;
|
||||
sde_cfg->has_ubwc_stats = true;
|
||||
} else if (IS_YUPIK_TARGET(hw_rev)) {
|
||||
sde_cfg->has_cwb_support = true;
|
||||
sde_cfg->has_qsync = true;
|
||||
|
@@ -275,6 +275,7 @@ enum {
|
||||
* @SDE_SSPP_FP16_GC FP16 GC color processing block support
|
||||
* @SDE_SSPP_FP16_CSC FP16 CSC color processing block support
|
||||
* @SDE_SSPP_FP16_UNMULT FP16 alpha unmult color processing block support
|
||||
* @SDE_SSPP_UBWC_STATS: Support for ubwc stats
|
||||
* @SDE_SSPP_MAX maximum value
|
||||
*/
|
||||
enum {
|
||||
@@ -311,6 +312,7 @@ enum {
|
||||
SDE_SSPP_FP16_GC,
|
||||
SDE_SSPP_FP16_CSC,
|
||||
SDE_SSPP_FP16_UNMULT,
|
||||
SDE_SSPP_UBWC_STATS,
|
||||
SDE_SSPP_MAX
|
||||
};
|
||||
|
||||
@@ -1544,6 +1546,7 @@ struct sde_perf_cfg {
|
||||
* @has_vig_p010 indicates if vig pipe supports p010 format
|
||||
* @has_fp16 indicates if FP16 format is supported on SSPP pipes
|
||||
* @has_precise_vsync_ts indicates if HW has vsyc timestamp logging capability
|
||||
* @has_ubwc_stats: indicates if ubwc stats feature is supported
|
||||
* @mdss_hw_block_size Max offset of MDSS_HW block (0 offset), used for debug
|
||||
* @inline_rot_formats formats supported by the inline rotator feature
|
||||
* @irq_offset_list list of sde_intr_irq_offsets to initialize irq table
|
||||
@@ -1629,6 +1632,8 @@ struct sde_mdss_cfg {
|
||||
bool has_vig_p010;
|
||||
bool has_fp16;
|
||||
bool has_precise_vsync_ts;
|
||||
bool has_ubwc_stats;
|
||||
|
||||
u32 mdss_hw_block_size;
|
||||
u32 mdss_count;
|
||||
struct sde_mdss_base_cfg mdss[MAX_BLOCKS];
|
||||
|
@@ -77,6 +77,10 @@
|
||||
#define SSPP_SRC_ADDR_SW_STATUS 0x70
|
||||
#define SSPP_CREQ_LUT_0 0x74
|
||||
#define SSPP_CREQ_LUT_1 0x78
|
||||
#define SSPP_UBWC_STATS_ROI 0x7C
|
||||
#define SSPP_UBWC_STATS_DATA 0x80
|
||||
#define SSPP_UBWC_STATS_ROI_REC1 0xB4
|
||||
#define SSPP_UBWC_STATS_DATA_REC1 0xB8
|
||||
#define SSPP_SW_PIX_EXT_C0_LR 0x100
|
||||
#define SSPP_SW_PIX_EXT_C0_TB 0x104
|
||||
#define SSPP_SW_PIX_EXT_C0_REQ_PIXELS 0x108
|
||||
@@ -96,8 +100,9 @@
|
||||
#define SSPP_TRAFFIC_SHAPER_REC1 0x158
|
||||
#define SSPP_EXCL_REC_SIZE 0x1B4
|
||||
#define SSPP_EXCL_REC_XY 0x1B8
|
||||
#define SSPP_META_ERROR_STATUS_REC1 0x1C4
|
||||
#define SSPP_UBWC_STATIC_CTRL_REC1 0x1C0
|
||||
#define SSPP_UBWC_ERROR_STATUS_REC1 0x1C8
|
||||
#define SSPP_META_ERROR_STATUS_REC1 0x1C4
|
||||
#define SSPP_VIG_OP_MODE 0x0
|
||||
#define SSPP_VIG_CSC_10_OP_MODE 0x0
|
||||
#define SSPP_TRAFFIC_SHAPER_BPC_MAX 0xFF
|
||||
@@ -436,7 +441,8 @@ static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx,
|
||||
SDE_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31));
|
||||
}
|
||||
|
||||
static void sde_hw_sspp_clear_ubwc_error(struct sde_hw_pipe *ctx, uint32_t multirect_index)
|
||||
static void sde_hw_sspp_clear_ubwc_error(struct sde_hw_pipe *ctx,
|
||||
enum sde_sspp_multirect_index multirect_index)
|
||||
{
|
||||
struct sde_hw_blk_reg_map *c;
|
||||
|
||||
@@ -445,7 +451,8 @@ static void sde_hw_sspp_clear_ubwc_error(struct sde_hw_pipe *ctx, uint32_t multi
|
||||
SDE_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS, BIT(31));
|
||||
}
|
||||
|
||||
static u32 sde_hw_sspp_get_ubwc_error(struct sde_hw_pipe *ctx, uint32_t multirect_index)
|
||||
static u32 sde_hw_sspp_get_ubwc_error(struct sde_hw_pipe *ctx,
|
||||
enum sde_sspp_multirect_index multirect_index)
|
||||
{
|
||||
struct sde_hw_blk_reg_map *c;
|
||||
u32 reg_code;
|
||||
@@ -457,7 +464,8 @@ static u32 sde_hw_sspp_get_ubwc_error(struct sde_hw_pipe *ctx, uint32_t multirec
|
||||
return reg_code;
|
||||
}
|
||||
|
||||
static void sde_hw_sspp_clear_ubwc_error_v1(struct sde_hw_pipe *ctx, uint32_t multirect_index)
|
||||
static void sde_hw_sspp_clear_ubwc_error_v1(struct sde_hw_pipe *ctx,
|
||||
enum sde_sspp_multirect_index multirect_index)
|
||||
{
|
||||
struct sde_hw_blk_reg_map *c;
|
||||
|
||||
@@ -469,7 +477,8 @@ static void sde_hw_sspp_clear_ubwc_error_v1(struct sde_hw_pipe *ctx, uint32_t mu
|
||||
SDE_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS, BIT(31));
|
||||
}
|
||||
|
||||
static u32 sde_hw_sspp_get_ubwc_error_v1(struct sde_hw_pipe *ctx, uint32_t multirect_index)
|
||||
static u32 sde_hw_sspp_get_ubwc_error_v1(struct sde_hw_pipe *ctx,
|
||||
enum sde_sspp_multirect_index multirect_index)
|
||||
{
|
||||
struct sde_hw_blk_reg_map *c;
|
||||
u32 reg_code;
|
||||
@@ -484,7 +493,8 @@ static u32 sde_hw_sspp_get_ubwc_error_v1(struct sde_hw_pipe *ctx, uint32_t multi
|
||||
return reg_code;
|
||||
}
|
||||
|
||||
static void sde_hw_sspp_clear_meta_error(struct sde_hw_pipe *ctx, uint32_t multirect_index)
|
||||
static void sde_hw_sspp_clear_meta_error(struct sde_hw_pipe *ctx,
|
||||
enum sde_sspp_multirect_index multirect_index)
|
||||
{
|
||||
struct sde_hw_blk_reg_map *c;
|
||||
|
||||
@@ -496,7 +506,8 @@ static void sde_hw_sspp_clear_meta_error(struct sde_hw_pipe *ctx, uint32_t multi
|
||||
SDE_REG_WRITE(c, SSPP_META_ERROR_STATUS, BIT(31));
|
||||
}
|
||||
|
||||
static u32 sde_hw_sspp_get_meta_error(struct sde_hw_pipe *ctx, uint32_t multirect_index)
|
||||
static u32 sde_hw_sspp_get_meta_error(struct sde_hw_pipe *ctx,
|
||||
enum sde_sspp_multirect_index multirect_index)
|
||||
{
|
||||
struct sde_hw_blk_reg_map *c;
|
||||
u32 reg_code;
|
||||
@@ -511,6 +522,75 @@ static u32 sde_hw_sspp_get_meta_error(struct sde_hw_pipe *ctx, uint32_t multirec
|
||||
return reg_code;
|
||||
}
|
||||
|
||||
static void sde_hw_sspp_ubwc_stats_set_roi(struct sde_hw_pipe *ctx,
|
||||
enum sde_sspp_multirect_index multirect_index,
|
||||
struct sde_drm_ubwc_stats_roi *roi)
|
||||
{
|
||||
struct sde_hw_blk_reg_map *c;
|
||||
u32 idx, ctrl_off, roi_off;
|
||||
u32 ctrl_val = 0, roi_val = 0;
|
||||
|
||||
if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
|
||||
return;
|
||||
|
||||
if (multirect_index == SDE_SSPP_RECT_SOLO || multirect_index == SDE_SSPP_RECT_0) {
|
||||
ctrl_off = SSPP_UBWC_STATIC_CTRL + idx;
|
||||
roi_off = SSPP_UBWC_STATS_ROI + idx;
|
||||
} else {
|
||||
ctrl_off = SSPP_UBWC_STATIC_CTRL_REC1 + idx;
|
||||
roi_off = SSPP_UBWC_STATS_ROI_REC1 + idx;
|
||||
}
|
||||
|
||||
c = &ctx->hw;
|
||||
|
||||
ctrl_val = SDE_REG_READ(c, ctrl_off);
|
||||
|
||||
if (roi) {
|
||||
ctrl_val |= BIT(24);
|
||||
if (roi->y_coord0) {
|
||||
ctrl_val |= BIT(25);
|
||||
roi_val |= roi->y_coord0;
|
||||
|
||||
if (roi->y_coord1) {
|
||||
ctrl_val |= BIT(26);
|
||||
roi_val |= (roi->y_coord1) << 0x10;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ctrl_val &= ~(BIT(24) | BIT(25) | BIT(26));
|
||||
}
|
||||
|
||||
SDE_REG_WRITE(c, ctrl_off, ctrl_val);
|
||||
SDE_REG_WRITE(c, roi_off, roi_val);
|
||||
}
|
||||
|
||||
static void sde_hw_sspp_ubwc_stats_get_data(struct sde_hw_pipe *ctx,
|
||||
enum sde_sspp_multirect_index multirect_index,
|
||||
struct sde_drm_ubwc_stats_data *data)
|
||||
{
|
||||
struct sde_hw_blk_reg_map *c;
|
||||
u32 idx, value = 0;
|
||||
int i;
|
||||
|
||||
if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx))
|
||||
return;
|
||||
|
||||
if (multirect_index == SDE_SSPP_RECT_SOLO || multirect_index == SDE_SSPP_RECT_0)
|
||||
idx += SSPP_UBWC_STATS_DATA;
|
||||
else
|
||||
idx += SSPP_UBWC_STATS_DATA_REC1;
|
||||
|
||||
c = &ctx->hw;
|
||||
|
||||
for (i = 0; i < UBWC_STATS_MAX_ROI; i++) {
|
||||
value = SDE_REG_READ(c, idx);
|
||||
data->worst_bw[i] = value & 0xFFFF;
|
||||
data->worst_bw_y_coord[i] = (value >> 0x10) & 0xFFFF;
|
||||
data->total_bw[i] = SDE_REG_READ(c, idx + 4);
|
||||
idx += 8;
|
||||
}
|
||||
}
|
||||
|
||||
static void sde_hw_sspp_setup_secure(struct sde_hw_pipe *ctx,
|
||||
enum sde_sspp_multirect_index rect_mode,
|
||||
bool enable)
|
||||
@@ -1373,6 +1453,11 @@ static void _setup_layer_ops(struct sde_hw_pipe *c,
|
||||
c->ops.setup_inverse_pma = sde_hw_sspp_setup_dgm_inverse_pma;
|
||||
else if (test_bit(SDE_SSPP_INVERSE_PMA, &features))
|
||||
c->ops.setup_inverse_pma = sde_hw_sspp_setup_inverse_pma;
|
||||
|
||||
if (test_bit(SDE_SSPP_UBWC_STATS, &features)) {
|
||||
c->ops.set_ubwc_stats_roi = sde_hw_sspp_ubwc_stats_set_roi;
|
||||
c->ops.get_ubwc_stats_data = sde_hw_sspp_ubwc_stats_get_data;
|
||||
}
|
||||
}
|
||||
|
||||
static struct sde_sspp_cfg *_sspp_offset(enum sde_sspp sspp,
|
||||
|
@@ -596,28 +596,52 @@ struct sde_hw_sspp_ops {
|
||||
* @ctx: Pointer to pipe context
|
||||
* @multirect_index: rec in use
|
||||
*/
|
||||
void (*clear_meta_error)(struct sde_hw_pipe *ctx, uint32_t multirect_index);
|
||||
void (*clear_meta_error)(struct sde_hw_pipe *ctx,
|
||||
enum sde_sspp_multirect_index multirect_index);
|
||||
|
||||
/**
|
||||
* get_meta_error - get the meta error-code
|
||||
* @ctx: Pointer to pipe context
|
||||
* @multirect_index: rec in use
|
||||
*/
|
||||
u32 (*get_meta_error)(struct sde_hw_pipe *ctx, uint32_t multirect_index);
|
||||
u32 (*get_meta_error)(struct sde_hw_pipe *ctx,
|
||||
enum sde_sspp_multirect_index multirect_index);
|
||||
|
||||
/**
|
||||
* clear_ubwc_error - clear the ubwc error-code registers
|
||||
* @ctx: Pointer to pipe context
|
||||
* @multirect_index: rec in use
|
||||
*/
|
||||
void (*clear_ubwc_error)(struct sde_hw_pipe *ctx, uint32_t multirect_index);
|
||||
void (*clear_ubwc_error)(struct sde_hw_pipe *ctx,
|
||||
enum sde_sspp_multirect_index multirect_index);
|
||||
|
||||
/**
|
||||
* get_ubwc_error - get the ubwc error-code
|
||||
* @ctx: Pointer to pipe context
|
||||
* @multirect_index: rec in use
|
||||
*/
|
||||
u32 (*get_ubwc_error)(struct sde_hw_pipe *ctx, uint32_t multirect_index);
|
||||
u32 (*get_ubwc_error)(struct sde_hw_pipe *ctx,
|
||||
enum sde_sspp_multirect_index multirect_index);
|
||||
|
||||
/**
|
||||
* get_ubwc_stats_data - get ubwc stats data
|
||||
* @ctx: Pointer to pipe context
|
||||
* @multirect_index: rec in use
|
||||
* @data: Pointer to ubwc data to populate
|
||||
*/
|
||||
void (*get_ubwc_stats_data)(struct sde_hw_pipe *ctx,
|
||||
enum sde_sspp_multirect_index multirect_index,
|
||||
struct sde_drm_ubwc_stats_data *data);
|
||||
|
||||
/**
|
||||
* set_ubwc_stats_roi - set ubwc stats roi
|
||||
* @ctx: Pointer to pipe context
|
||||
* @multirect_index: rec in use
|
||||
* @roi: roi to be programmed
|
||||
*/
|
||||
void (*set_ubwc_stats_roi)(struct sde_hw_pipe *ctx,
|
||||
enum sde_sspp_multirect_index multirect_index,
|
||||
struct sde_drm_ubwc_stats_roi *roi);
|
||||
|
||||
/**
|
||||
* setup_fp16_csc - set FP16 CSC cp block
|
||||
|
@@ -2854,6 +2854,7 @@ static void _sde_plane_map_prop_to_dirty_bits(void)
|
||||
plane_prop_array[PLANE_PROP_SRC_CONFIG] =
|
||||
plane_prop_array[PLANE_PROP_ZPOS] =
|
||||
plane_prop_array[PLANE_PROP_EXCL_RECT_V1] =
|
||||
plane_prop_array[PLANE_PROP_UBWC_STATS_ROI] =
|
||||
SDE_PLANE_DIRTY_RECTS;
|
||||
|
||||
plane_prop_array[PLANE_PROP_CSC_V1] =
|
||||
@@ -3141,6 +3142,15 @@ static void _sde_plane_update_format_and_rects(struct sde_plane *psde,
|
||||
if (psde->pipe_hw->ops.setup_dgm_csc)
|
||||
psde->pipe_hw->ops.setup_dgm_csc(psde->pipe_hw,
|
||||
pstate->multirect_index, psde->csc_usr_ptr);
|
||||
|
||||
if (psde->pipe_hw->ops.set_ubwc_stats_roi) {
|
||||
if (SDE_FORMAT_IS_UBWC(fmt) && !SDE_FORMAT_IS_YUV(fmt))
|
||||
psde->pipe_hw->ops.set_ubwc_stats_roi(psde->pipe_hw,
|
||||
pstate->multirect_index, &pstate->ubwc_stats_roi);
|
||||
else
|
||||
psde->pipe_hw->ops.set_ubwc_stats_roi(psde->pipe_hw,
|
||||
pstate->multirect_index, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void _sde_plane_update_sharpening(struct sde_plane *psde)
|
||||
@@ -3862,6 +3872,9 @@ static void _sde_plane_install_properties(struct drm_plane *plane,
|
||||
ARRAY_SIZE(e_fb_translation_mode), 0,
|
||||
PLANE_PROP_FB_TRANSLATION_MODE);
|
||||
|
||||
if (psde->pipe_hw->ops.set_ubwc_stats_roi)
|
||||
msm_property_install_range(&psde->property_info, "ubwc_stats_roi",
|
||||
0, 0, 0xFFFFFFFF, 0, PLANE_PROP_UBWC_STATS_ROI);
|
||||
kfree(info);
|
||||
}
|
||||
|
||||
@@ -4077,6 +4090,30 @@ static void _sde_plane_set_excl_rect_v1(struct sde_plane *psde,
|
||||
pstate->excl_rect.w, pstate->excl_rect.h);
|
||||
}
|
||||
|
||||
static void _sde_plane_set_ubwc_stats_roi(struct sde_plane *psde,
|
||||
struct sde_plane_state *pstate, uint64_t roi)
|
||||
{
|
||||
uint16_t y0, y1;
|
||||
|
||||
if (!psde || !pstate) {
|
||||
SDE_ERROR("invalid argument(s)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
y0 = roi & 0xFFFF;
|
||||
y1 = (roi >> 0x10) & 0xFFFF;
|
||||
|
||||
if (y0 > psde->pipe_cfg.src_rect.h || y1 > psde->pipe_cfg.src_rect.h) {
|
||||
SDE_ERROR_PLANE(psde, "invalid ubwc roi y0 0x%x, y1 0x%x, src height 0x%x",
|
||||
y0, y1, psde->pipe_cfg.src_rect.h);
|
||||
y0 = 0;
|
||||
y1 = 0;
|
||||
}
|
||||
|
||||
pstate->ubwc_stats_roi.y_coord0 = y0;
|
||||
pstate->ubwc_stats_roi.y_coord1 = y1;
|
||||
}
|
||||
|
||||
static int sde_plane_atomic_set_property(struct drm_plane *plane,
|
||||
struct drm_plane_state *state, struct drm_property *property,
|
||||
uint64_t val)
|
||||
@@ -4118,6 +4155,9 @@ static int sde_plane_atomic_set_property(struct drm_plane *plane,
|
||||
_sde_plane_set_excl_rect_v1(psde, pstate,
|
||||
(void *)(uintptr_t)val);
|
||||
break;
|
||||
case PLANE_PROP_UBWC_STATS_ROI:
|
||||
_sde_plane_set_ubwc_stats_roi(psde, pstate, val);
|
||||
break;
|
||||
default:
|
||||
/* nothing to do */
|
||||
break;
|
||||
@@ -4385,76 +4425,51 @@ static void sde_plane_reset(struct drm_plane *plane)
|
||||
plane->state = &pstate->base;
|
||||
}
|
||||
|
||||
u32 sde_plane_get_ubwc_error(struct drm_plane *plane)
|
||||
{
|
||||
u32 ubwc_error = 0;
|
||||
struct sde_plane *psde;
|
||||
struct sde_plane_state *pstate;
|
||||
|
||||
if (!plane) {
|
||||
SDE_ERROR("invalid plane\n");
|
||||
return 0;
|
||||
}
|
||||
psde = to_sde_plane(plane);
|
||||
pstate = to_sde_plane_state(plane->state);
|
||||
|
||||
if (!psde->is_virtual && psde->pipe_hw->ops.get_ubwc_error)
|
||||
ubwc_error = psde->pipe_hw->ops.get_ubwc_error(psde->pipe_hw,
|
||||
pstate->multirect_index);
|
||||
|
||||
return ubwc_error;
|
||||
}
|
||||
|
||||
void sde_plane_clear_ubwc_error(struct drm_plane *plane)
|
||||
void sde_plane_get_frame_data(struct drm_plane *plane,
|
||||
struct sde_drm_plane_frame_data *data)
|
||||
{
|
||||
struct sde_plane *psde;
|
||||
struct sde_plane_state *pstate;
|
||||
struct sde_drm_ubwc_stats_data *ubwc_stats;
|
||||
|
||||
if (!plane) {
|
||||
SDE_ERROR("invalid plane\n");
|
||||
return;
|
||||
}
|
||||
|
||||
psde = to_sde_plane(plane);
|
||||
pstate = to_sde_plane_state(plane->state);
|
||||
ubwc_stats = &data->ubwc_stats;
|
||||
|
||||
if (psde->pipe_hw->ops.clear_ubwc_error)
|
||||
data->plane_id = DRMID(plane);
|
||||
|
||||
if (psde->pipe_hw->ops.get_ubwc_stats_data) {
|
||||
memcpy(&ubwc_stats->roi, &pstate->ubwc_stats_roi,
|
||||
sizeof(struct sde_drm_ubwc_stats_roi));
|
||||
psde->pipe_hw->ops.get_ubwc_stats_data(psde->pipe_hw,
|
||||
pstate->multirect_index, ubwc_stats);
|
||||
}
|
||||
|
||||
if (psde->pipe_hw->ops.get_ubwc_error)
|
||||
ubwc_stats->error = psde->pipe_hw->ops.get_ubwc_error(psde->pipe_hw,
|
||||
pstate->multirect_index);
|
||||
|
||||
if (psde->pipe_hw->ops.clear_ubwc_error && ubwc_stats->error)
|
||||
psde->pipe_hw->ops.clear_ubwc_error(psde->pipe_hw, pstate->multirect_index);
|
||||
}
|
||||
|
||||
u32 sde_plane_get_meta_error(struct drm_plane *plane)
|
||||
{
|
||||
u32 meta_error = 0;
|
||||
struct sde_plane *psde;
|
||||
struct sde_plane_state *pstate;
|
||||
|
||||
if (!plane) {
|
||||
SDE_ERROR("invalid plane\n");
|
||||
return 0;
|
||||
}
|
||||
psde = to_sde_plane(plane);
|
||||
pstate = to_sde_plane_state(plane->state);
|
||||
|
||||
if (psde->pipe_hw->ops.get_meta_error)
|
||||
meta_error = psde->pipe_hw->ops.get_meta_error(psde->pipe_hw,
|
||||
ubwc_stats->meta_error = psde->pipe_hw->ops.get_meta_error(psde->pipe_hw,
|
||||
pstate->multirect_index);
|
||||
|
||||
return meta_error;
|
||||
}
|
||||
|
||||
void sde_plane_clear_meta_error(struct drm_plane *plane)
|
||||
{
|
||||
struct sde_plane *psde;
|
||||
struct sde_plane_state *pstate;
|
||||
|
||||
if (!plane) {
|
||||
SDE_ERROR("invalid plane\n");
|
||||
return;
|
||||
}
|
||||
psde = to_sde_plane(plane);
|
||||
pstate = to_sde_plane_state(plane->state);
|
||||
|
||||
if (psde->pipe_hw->ops.clear_meta_error)
|
||||
if (psde->pipe_hw->ops.clear_meta_error && ubwc_stats->meta_error)
|
||||
psde->pipe_hw->ops.clear_meta_error(psde->pipe_hw, pstate->multirect_index);
|
||||
|
||||
if (ubwc_stats->error || ubwc_stats->meta_error) {
|
||||
SDE_EVT32(DRMID(plane), ubwc_stats->error, ubwc_stats->meta_error,
|
||||
SDE_EVTLOG_ERROR);
|
||||
SDE_DEBUG_PLANE(psde, "plane%d ubwc_error %d meta_error %d\n",
|
||||
ubwc_stats->error, ubwc_stats->meta_error);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
@@ -111,6 +111,7 @@ enum sde_plane_sclcheck_state {
|
||||
* @static_cache_state: plane cache state for static image
|
||||
* @cdp_cfg: CDP configuration
|
||||
* @cont_splash_populated: State was populated as part of cont. splash
|
||||
* @ubwc_stats_roi: cached roi for ubwc stats
|
||||
*/
|
||||
struct sde_plane_state {
|
||||
struct drm_plane_state base;
|
||||
@@ -144,6 +145,8 @@ struct sde_plane_state {
|
||||
struct sde_hw_pipe_cdp_cfg cdp_cfg;
|
||||
|
||||
bool cont_splash_populated;
|
||||
|
||||
struct sde_drm_ubwc_stats_roi ubwc_stats_roi;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -314,30 +317,13 @@ bool sde_plane_is_sec_ui_allowed(struct drm_plane *plane);
|
||||
*/
|
||||
void sde_plane_secure_ctrl_xin_client(struct drm_plane *plane,
|
||||
struct drm_crtc *crtc);
|
||||
|
||||
/*
|
||||
* sde_plane_get_ubwc_error - gets the ubwc error code
|
||||
* sde_plane_get_frame_data - gets the plane frame data
|
||||
* @plane: Pointer to DRM plane object
|
||||
* @frame_data: Pointer to plane frame data structure
|
||||
*/
|
||||
u32 sde_plane_get_ubwc_error(struct drm_plane *plane);
|
||||
|
||||
/*
|
||||
* sde_plane_clear_ubwc_error - clears the ubwc error code
|
||||
* @plane: Pointer to DRM plane object
|
||||
*/
|
||||
void sde_plane_clear_ubwc_error(struct drm_plane *plane);
|
||||
|
||||
/*
|
||||
* sde_plane_get_meta_error - gets the meta error code
|
||||
* @plane: Pointer to DRM plane object
|
||||
*/
|
||||
u32 sde_plane_get_meta_error(struct drm_plane *plane);
|
||||
|
||||
/*
|
||||
* sde_plane_clear_meta_error - clears the meta error code
|
||||
* @plane: Pointer to DRM plane object
|
||||
*/
|
||||
void sde_plane_clear_meta_error(struct drm_plane *plane);
|
||||
void sde_plane_get_frame_data(struct drm_plane *plane,
|
||||
struct sde_drm_plane_frame_data *frame_data);
|
||||
|
||||
/*
|
||||
* sde_plane_setup_src_split_order - enable/disable pipe's src_split_order
|
||||
|
Reference in New Issue
Block a user