drm/amd/display: Add DCN3 VPG
authorBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Mon, 25 May 2020 17:15:04 +0000 (13:15 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 1 Jul 2020 05:59:15 +0000 (01:59 -0400)
Video Package generator.

used to prepare avi info, DP info etc

Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h [new file with mode: 0644]

diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c
new file mode 100644 (file)
index 0000000..9c0020c
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2020 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ *  and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+
+#include "dc_bios_types.h"
+#include "dcn30_vpg.h"
+#include "reg_helper.h"
+
+#define DC_LOGGER \
+               vpg3->base.ctx->logger
+
+#define REG(reg)\
+       (vpg3->regs->reg)
+
+#undef FN
+#define FN(reg_name, field_name) \
+       vpg3->vpg_shift->field_name, vpg3->vpg_mask->field_name
+
+
+#define CTX \
+       vpg3->base.ctx
+
+
+static void vpg3_update_generic_info_packet(
+       struct vpg *vpg,
+       uint32_t packet_index,
+       const struct dc_info_packet *info_packet)
+{
+       struct dcn30_vpg *vpg3 = DCN30_VPG_FROM_VPG(vpg);
+       uint32_t i;
+
+       /* TODOFPGA Figure out a proper number for max_retries polling for lock
+        * use 50 for now.
+        */
+       uint32_t max_retries = 50;
+
+       if (packet_index > 14)
+               ASSERT(0);
+
+       /* poll dig_update_lock is not locked -> asic internal signal
+        * assume otg master lock will unlock it
+        */
+       /* REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_LOCK_STATUS,
+        *              0, 10, max_retries);
+        */
+
+       /* TODO: Check if this is required */
+       /* check if HW reading GSP memory */
+       REG_WAIT(VPG_GENERIC_STATUS, VPG_GENERIC_CONFLICT_OCCURED,
+                       0, 10, max_retries);
+
+       /* HW does is not reading GSP memory not reading too long ->
+        * something wrong. clear GPS memory access and notify?
+        * hw SW is writing to GSP memory
+        */
+       REG_UPDATE(VPG_GENERIC_STATUS, VPG_GENERIC_CONFLICT_CLR, 1);
+
+       /* choose which generic packet to use */
+       REG_UPDATE(VPG_GENERIC_PACKET_ACCESS_CTRL,
+                       VPG_GENERIC_DATA_INDEX, packet_index*9);
+
+       /* write generic packet header
+        * (4th byte is for GENERIC0 only)
+        */
+       REG_SET_4(VPG_GENERIC_PACKET_DATA, 0,
+                       VPG_GENERIC_DATA_BYTE0, info_packet->hb0,
+                       VPG_GENERIC_DATA_BYTE1, info_packet->hb1,
+                       VPG_GENERIC_DATA_BYTE2, info_packet->hb2,
+                       VPG_GENERIC_DATA_BYTE3, info_packet->hb3);
+
+       /* write generic packet contents
+        * (we never use last 4 bytes)
+        * there are 8 (0-7) mmDIG0_AFMT_GENERIC0_x registers
+        */
+       {
+               const uint32_t *content =
+                       (const uint32_t *) &info_packet->sb[0];
+
+               for (i = 0; i < 8; i++) {
+                       REG_WRITE(VPG_GENERIC_PACKET_DATA, *content++);
+               }
+       }
+
+       /* atomically update double-buffered GENERIC0 registers in frame mode
+        * (update at next block_update when block_update_lock == 0).
+        */
+       switch (packet_index) {
+       case 0:
+               REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+                               VPG_GENERIC0_FRAME_UPDATE, 1);
+               break;
+       case 1:
+               REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+                               VPG_GENERIC1_FRAME_UPDATE, 1);
+               break;
+       case 2:
+               REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+                               VPG_GENERIC2_FRAME_UPDATE, 1);
+               break;
+       case 3:
+               REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+                               VPG_GENERIC3_FRAME_UPDATE, 1);
+               break;
+       case 4:
+               REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+                               VPG_GENERIC4_FRAME_UPDATE, 1);
+               break;
+       case 5:
+               REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+                               VPG_GENERIC5_FRAME_UPDATE, 1);
+               break;
+       case 6:
+               REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+                               VPG_GENERIC6_FRAME_UPDATE, 1);
+               break;
+       case 7:
+               REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+                               VPG_GENERIC7_FRAME_UPDATE, 1);
+               break;
+       case 8:
+               REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+                               VPG_GENERIC8_FRAME_UPDATE, 1);
+               break;
+       case 9:
+               REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+                               VPG_GENERIC9_FRAME_UPDATE, 1);
+               break;
+       case 10:
+               REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+                               VPG_GENERIC10_FRAME_UPDATE, 1);
+               break;
+       case 11:
+               REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+                               VPG_GENERIC11_FRAME_UPDATE, 1);
+               break;
+       case 12:
+               REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+                               VPG_GENERIC12_FRAME_UPDATE, 1);
+               break;
+       case 13:
+               REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+                               VPG_GENERIC13_FRAME_UPDATE, 1);
+               break;
+       case 14:
+               REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL,
+                               VPG_GENERIC14_FRAME_UPDATE, 1);
+               break;
+       default:
+               break;
+       }
+}
+
+static struct vpg_funcs dcn30_vpg_funcs = {
+       .update_generic_info_packet     = vpg3_update_generic_info_packet,
+};
+
+void vpg3_construct(struct dcn30_vpg *vpg3,
+       struct dc_context *ctx,
+       uint32_t inst,
+       const struct dcn30_vpg_registers *vpg_regs,
+       const struct dcn30_vpg_shift *vpg_shift,
+       const struct dcn30_vpg_mask *vpg_mask)
+{
+       vpg3->base.ctx = ctx;
+
+       vpg3->base.inst = inst;
+       vpg3->base.funcs = &dcn30_vpg_funcs;
+
+       vpg3->regs = vpg_regs;
+       vpg3->vpg_shift = vpg_shift;
+       vpg3->vpg_mask = vpg_mask;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h
new file mode 100644 (file)
index 0000000..0284092
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2020 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_DCN30_VPG_H__
+#define __DAL_DCN30_VPG_H__
+
+
+#define DCN30_VPG_FROM_VPG(vpg)\
+       container_of(vpg, struct dcn30_vpg, base)
+
+#define VPG_DCN3_REG_LIST(id) \
+       SRI(VPG_GENERIC_STATUS, VPG, id), \
+       SRI(VPG_GENERIC_PACKET_ACCESS_CTRL, VPG, id), \
+       SRI(VPG_GENERIC_PACKET_DATA, VPG, id), \
+       SRI(VPG_GSP_FRAME_UPDATE_CTRL, VPG, id)
+
+struct dcn30_vpg_registers {
+       uint32_t VPG_GENERIC_STATUS;
+       uint32_t VPG_GENERIC_PACKET_ACCESS_CTRL;
+       uint32_t VPG_GENERIC_PACKET_DATA;
+       uint32_t VPG_GSP_FRAME_UPDATE_CTRL;
+};
+
+#define DCN3_VPG_MASK_SH_LIST(mask_sh)\
+       SE_SF(VPG0_VPG_GENERIC_STATUS, VPG_GENERIC_CONFLICT_OCCURED, mask_sh),\
+       SE_SF(VPG0_VPG_GENERIC_STATUS, VPG_GENERIC_CONFLICT_CLR, mask_sh),\
+       SE_SF(VPG0_VPG_GENERIC_PACKET_ACCESS_CTRL, VPG_GENERIC_DATA_INDEX, mask_sh),\
+       SE_SF(VPG0_VPG_GENERIC_PACKET_DATA, VPG_GENERIC_DATA_BYTE0, mask_sh),\
+       SE_SF(VPG0_VPG_GENERIC_PACKET_DATA, VPG_GENERIC_DATA_BYTE1, mask_sh),\
+       SE_SF(VPG0_VPG_GENERIC_PACKET_DATA, VPG_GENERIC_DATA_BYTE2, mask_sh),\
+       SE_SF(VPG0_VPG_GENERIC_PACKET_DATA, VPG_GENERIC_DATA_BYTE3, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC0_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC1_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC2_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC3_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC4_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC5_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC6_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC7_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC8_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC9_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC10_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC11_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC12_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC13_FRAME_UPDATE, mask_sh),\
+       SE_SF(VPG0_VPG_GSP_FRAME_UPDATE_CTRL, VPG_GENERIC14_FRAME_UPDATE, mask_sh)
+
+#define VPG_DCN3_REG_FIELD_LIST(type) \
+       type VPG_GENERIC_CONFLICT_OCCURED;\
+       type VPG_GENERIC_CONFLICT_CLR;\
+       type VPG_GENERIC_DATA_INDEX;\
+       type VPG_GENERIC_DATA_BYTE0;\
+       type VPG_GENERIC_DATA_BYTE1;\
+       type VPG_GENERIC_DATA_BYTE2;\
+       type VPG_GENERIC_DATA_BYTE3;\
+       type VPG_GENERIC0_FRAME_UPDATE;\
+       type VPG_GENERIC1_FRAME_UPDATE;\
+       type VPG_GENERIC2_FRAME_UPDATE;\
+       type VPG_GENERIC3_FRAME_UPDATE;\
+       type VPG_GENERIC4_FRAME_UPDATE;\
+       type VPG_GENERIC5_FRAME_UPDATE;\
+       type VPG_GENERIC6_FRAME_UPDATE;\
+       type VPG_GENERIC7_FRAME_UPDATE;\
+       type VPG_GENERIC8_FRAME_UPDATE;\
+       type VPG_GENERIC9_FRAME_UPDATE;\
+       type VPG_GENERIC10_FRAME_UPDATE;\
+       type VPG_GENERIC11_FRAME_UPDATE;\
+       type VPG_GENERIC12_FRAME_UPDATE;\
+       type VPG_GENERIC13_FRAME_UPDATE;\
+       type VPG_GENERIC14_FRAME_UPDATE
+
+
+struct dcn30_vpg_shift {
+       VPG_DCN3_REG_FIELD_LIST(uint8_t);
+};
+
+struct dcn30_vpg_mask {
+       VPG_DCN3_REG_FIELD_LIST(uint32_t);
+};
+
+struct vpg;
+
+struct vpg_funcs {
+       void (*update_generic_info_packet)(
+               struct vpg *vpg,
+               uint32_t packet_index,
+               const struct dc_info_packet *info_packet);
+};
+
+struct vpg {
+       const struct vpg_funcs *funcs;
+       struct dc_context *ctx;
+       int inst;
+};
+
+struct dcn30_vpg {
+       struct vpg base;
+       const struct dcn30_vpg_registers *regs;
+       const struct dcn30_vpg_shift *vpg_shift;
+       const struct dcn30_vpg_mask *vpg_mask;
+};
+
+void vpg3_construct(struct dcn30_vpg *vpg3,
+       struct dc_context *ctx,
+       uint32_t inst,
+       const struct dcn30_vpg_registers *vpg_regs,
+       const struct dcn30_vpg_shift *vpg_shift,
+       const struct dcn30_vpg_mask *vpg_mask);
+
+
+#endif