#include "dm_services.h"
#include "reg_helper.h"
+#include "dc_dmub_srv.h"
+
#define DC_LOGGER_INIT(logger)
#define REG(reg)\
dml_dlg_attr->refcyc_per_meta_chunk_flip_l, dlg_attr.refcyc_per_meta_chunk_flip_l);
}
+static void program_video_progressive_dmcub(
+ struct dc_dmub_srv *dmcub,
+ struct hubp *hubp,
+ const struct dc_plane_address *address,
+ bool flip_immediate)
+{
+ struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp);
+ struct dmub_rb_cmd_flip surface_flip = { 0 };
+
+ surface_flip.header.type = DMUB_CMD__SURFACE_FLIP;
+
+ surface_flip.flip.addr_type = address->type;
+ surface_flip.flip.immediate = flip_immediate;
+ surface_flip.flip.vmid = address->vmid;
+
+ surface_flip.flip.hubp_inst = hubp->inst;
+ surface_flip.flip.tmz_surface = address->tmz_surface;
+
+ switch (address->type) {
+ case PLN_ADDR_TYPE_GRAPHICS:
+ if (address->grph.addr.quad_part == 0)
+ return;
+
+ if (address->grph.meta_addr.quad_part != 0) {
+ surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS =
+ address->grph.meta_addr.low_part;
+ surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH =
+ address->grph.meta_addr.high_part;
+ }
+
+ surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS =
+ address->grph.addr.low_part;
+ surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH =
+ address->grph.addr.high_part;
+ break;
+ case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
+ if (address->video_progressive.luma_addr.quad_part == 0
+ || address->video_progressive.chroma_addr.quad_part == 0)
+ return;
+
+ if (address->video_progressive.luma_meta_addr.quad_part != 0) {
+ surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS =
+ address->video_progressive.luma_meta_addr.low_part;
+ surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH =
+ address->video_progressive.luma_meta_addr.high_part;
+
+ surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_C =
+ address->video_progressive.chroma_meta_addr.low_part;
+ surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C =
+ address->video_progressive.chroma_meta_addr.high_part;
+ }
+
+ surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS =
+ address->video_progressive.luma_addr.low_part;
+ surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH =
+ address->video_progressive.luma_addr.high_part;
+
+ surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_C =
+ address->video_progressive.chroma_addr.low_part;
+ surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C =
+ address->video_progressive.chroma_addr.high_part;
+
+ break;
+ case PLN_ADDR_TYPE_GRPH_STEREO:
+ if (address->grph_stereo.left_addr.quad_part == 0)
+ return;
+ if (address->grph_stereo.right_addr.quad_part == 0)
+ return;
+
+ surface_flip.flip.grph_stereo = true;
+
+ if (address->grph_stereo.right_meta_addr.quad_part != 0) {
+ surface_flip.flip.DCSURF_SECONDARY_META_SURFACE_ADDRESS =
+ address->grph_stereo.right_meta_addr.low_part;
+ surface_flip.flip.DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH =
+ address->grph_stereo.right_meta_addr.high_part;
+ }
+
+ if (address->grph_stereo.left_meta_addr.quad_part != 0) {
+ surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS =
+ address->grph_stereo.left_meta_addr.low_part;
+ surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH =
+ address->grph_stereo.left_meta_addr.high_part;
+ }
+
+ surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS =
+ address->grph_stereo.left_addr.low_part;
+ surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH =
+ address->grph_stereo.left_addr.high_part;
+
+ surface_flip.flip.DCSURF_SECONDARY_SURFACE_ADDRESS =
+ address->grph_stereo.right_addr.low_part;
+ surface_flip.flip.DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH =
+ address->grph_stereo.right_addr.high_part;
+
+ break;
+
+ }
+
+ PERF_TRACE(); // TODO: remove after performance is stable.
+ dc_dmub_srv_cmd_queue(dmcub, &surface_flip.header);
+ PERF_TRACE(); // TODO: remove after performance is stable.
+ dc_dmub_srv_cmd_execute(dmcub);
+ PERF_TRACE(); // TODO: remove after performance is stable.
+ dc_dmub_srv_wait_idle(dmcub);
+}
+
bool hubp21_program_surface_flip_and_addr(
struct hubp *hubp,
const struct dc_plane_address *address,
struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp);
struct dc_debug_options *debug = &hubp->ctx->dc->debug;
+
+ if (hubp->ctx->dc->debug.enable_dmcub_surface_flip) {
+ program_video_progressive_dmcub(hubp->ctx->dmub_srv, hubp, address, flip_immediate);
+ hubp->request_address = *address;
+ return true;
+ }
+
//program flip type
REG_UPDATE(DCSURF_FLIP_CONTROL,
SURFACE_FLIP_TYPE, flip_immediate);
#include "dmub_cmd_dal.h"
#include "dmub_cmd_vbios.h"
#include "atomfirmware.h"
-
+#include "dc_hw_types.h"
#define DMUB_RB_CMD_SIZE 64
#define DMUB_RB_MAX_ENTRY 128
#define DMUB_RB_SIZE (DMUB_RB_CMD_SIZE * DMUB_RB_MAX_ENTRY)
#define REG_SET_MASK 0xFFFF
+
/*
* Command IDs should be treated as stable ABI.
* Do not reuse or modify IDs.
DMUB_CMD__REG_SEQ_FIELD_UPDATE_SEQ = 2,
DMUB_CMD__REG_SEQ_BURST_WRITE = 3,
DMUB_CMD__REG_REG_WAIT = 4,
+ DMUB_CMD__SURFACE_FLIP = 5,
DMUB_CMD__PSR = 64,
DMUB_CMD__VBIOS = 128,
};
struct dmub_cmd_reg_wait_data reg_wait;
};
+#ifndef PHYSICAL_ADDRESS_LOC
+#define PHYSICAL_ADDRESS_LOC union large_integer
+#endif
+
+struct dmub_cmd_surface_flip {
+ uint32_t DCSURF_SURFACE_CONTROL;
+ uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH;
+ uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS;
+ uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH;
+ uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS;
+ uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C;
+ uint32_t DCSURF_PRIMARY_META_SURFACE_ADDRESS_C;
+ uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C;
+ uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_C;
+ uint32_t DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH;
+ uint32_t DCSURF_SECONDARY_META_SURFACE_ADDRESS;
+ uint32_t DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH;
+ uint32_t DCSURF_SECONDARY_SURFACE_ADDRESS;
+ enum dc_plane_addr_type addr_type;
+ uint8_t hubp_inst;
+ bool tmz_surface;
+ bool immediate;
+ uint8_t vmid;
+ bool grph_stereo;
+};
+
+struct dmub_rb_cmd_flip {
+ struct dmub_cmd_header header;
+ struct dmub_cmd_surface_flip flip;
+};
+
struct dmub_cmd_digx_encoder_control_data {
union dig_encoder_control_parameters_v1_5 dig;
};
struct dmub_rb_cmd_psr_enable psr_enable;
struct dmub_rb_cmd_psr_copy_settings psr_copy_settings;
struct dmub_rb_cmd_psr_set_level psr_set_level;
+ struct dmub_rb_cmd_flip surface_flip;
};
#pragma pack(pop)
static inline bool dmub_rb_push_front(struct dmub_rb *rb,
const struct dmub_cmd_header *cmd)
{
- uint8_t *wt_ptr = (uint8_t *)(rb->base_address) + rb->wrpt;
+ uint64_t volatile *dst = (uint64_t volatile *)(rb->base_address) + rb->wrpt / sizeof(uint64_t);
+ const uint64_t *src = (const uint64_t *)cmd;
+ int i;
if (dmub_rb_full(rb))
return false;
- dmub_memcpy(wt_ptr, cmd, DMUB_RB_CMD_SIZE);
+ // copying data
+ for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++)
+ *dst++ = *src++;
+
rb->wrpt += DMUB_RB_CMD_SIZE;
if (rb->wrpt >= rb->capacity)
static inline void dmub_rb_flush_pending(const struct dmub_rb *rb)
{
- uint8_t buf[DMUB_RB_CMD_SIZE];
uint32_t rptr = rb->rptr;
uint32_t wptr = rb->wrpt;
while (rptr != wptr) {
- const uint8_t *data = (const uint8_t *)rb->base_address + rptr;
+ uint64_t volatile *data = (uint64_t volatile *)rb->base_address + rptr / sizeof(uint64_t);
+ //uint64_t volatile *p = (uint64_t volatile *)data;
+ uint64_t temp;
+ int i;
- dmub_memcpy(buf, data, DMUB_RB_CMD_SIZE);
+ for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++)
+ temp = *data++;
rptr += DMUB_RB_CMD_SIZE;
if (rptr >= rb->capacity)