@@ -285,18 +285,122 @@ static int d71_compiz_init(struct d71_dev *d71,
return 0;
}
+static void d71_improc_update(struct komeda_component *c,
+ struct komeda_component_state *state)
+{
+ struct komeda_improc_state *st = to_improc_st(state);
+ u32 __iomem *reg = c->reg;
+ u32 index, input_hw_id;
+
+ for_each_changed_input(state, index) {
+ input_hw_id = state->active_inputs & BIT(index) ?
+ to_d71_input_id(&state->inputs[index]) : 0;
+ malidp_write32(reg, BLK_INPUT_ID0 + index * 4, input_hw_id);
+ }
+
+ malidp_write32(reg, BLK_SIZE, HV_SIZE(st->hsize, st->vsize));
+}
+
+struct komeda_component_funcs d71_improc_funcs = {
+ .update = d71_improc_update,
+ .disable = d71_component_disable,
+};
+
static int d71_improc_init(struct d71_dev *d71,
struct block_header *blk, u32 __iomem *reg)
{
- DRM_INFO("Detect D71_improc.\n");
+ struct komeda_component *c;
+ struct komeda_improc *improc;
+ u32 blk_id = BLOCK_INFO_BLK_ID(blk->block_info);
+ u32 value;
+
+ c = komeda_component_add(&d71->pipes[blk_id]->base, sizeof(*improc),
+ KOMEDA_COMPONENT_IPS0 + blk_id,
+ BLOCK_INFO_INPUT_ID(blk->block_info),
+ &d71_improc_funcs, IPS_NUM_INPUT_IDS,
+ get_valid_inputs(blk),
+ IPS_NUM_OUTPUT_IDS, reg, "DOU%d_IPS", blk_id);
+ if (!c) {
+ DRM_ERROR("Failed to add improc component\n");
+ return -EINVAL;
+ }
+
+ improc = to_improc(c);
+ improc->supported_color_depths = BIT(8) | BIT(10);
+ improc->supported_color_formats = DRM_COLOR_FORMAT_RGB444 |
+ DRM_COLOR_FORMAT_YCRCB444 |
+ DRM_COLOR_FORMAT_YCRCB422;
+ value = malidp_read32(reg, BLK_INFO);
+ if (value & IPS_INFO_CHD420)
+ improc->supported_color_formats |= DRM_COLOR_FORMAT_YCRCB420;
+
+ improc->supports_csc = true;
+ improc->supports_gamma = true;
return 0;
}
+static void d71_timing_ctrlr_disable(struct komeda_component *c)
+{
+ malidp_write32_mask(c->reg, BLK_CONTROL, BS_CTRL_EN, 0);
+}
+
+static void d71_timing_ctrlr_update(struct komeda_component *c,
+ struct komeda_component_state *state)
+{
+ struct drm_crtc_state *crtc_st = state->crtc->state;
+ u32 __iomem *reg = c->reg;
+ struct videomode vm;
+ u32 value;
+
+ drm_display_mode_to_videomode(&crtc_st->adjusted_mode, &vm);
+
+ malidp_write32(reg, BS_ACTIVESIZE, HV_SIZE(vm.hactive, vm.vactive));
+ malidp_write32(reg, BS_HINTERVALS, BS_H_INTVALS(vm.hfront_porch,
+ vm.hback_porch));
+ malidp_write32(reg, BS_VINTERVALS, BS_V_INTVALS(vm.vfront_porch,
+ vm.vback_porch));
+
+ value = BS_SYNC_VSW(vm.vsync_len) | BS_SYNC_HSW(vm.hsync_len);
+ value |= vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ? BS_SYNC_VSP : 0;
+ value |= vm.flags & DISPLAY_FLAGS_HSYNC_HIGH ? BS_SYNC_HSP : 0;
+ malidp_write32(reg, BS_SYNC, value);
+
+ malidp_write32(reg, BS_PROG_LINE, D71_DEFAULT_PREPRETCH_LINE - 1);
+ malidp_write32(reg, BS_PREFETCH_LINE, D71_DEFAULT_PREPRETCH_LINE);
+
+ /* configure bs control register */
+ value = BS_CTRL_EN | BS_CTRL_VM;
+
+ malidp_write32(reg, BLK_CONTROL, value);
+}
+
+struct komeda_component_funcs d71_timing_ctrlr_funcs = {
+ .update = d71_timing_ctrlr_update,
+ .disable = d71_timing_ctrlr_disable,
+};
+
static int d71_timing_ctrlr_init(struct d71_dev *d71,
struct block_header *blk, u32 __iomem *reg)
{
- DRM_INFO("Detect D71_timing_ctrlr.\n");
+ struct komeda_component *c;
+ struct komeda_timing_ctrlr *ctrlr;
+ u32 blk_id = BLOCK_INFO_BLK_ID(blk->block_info);
+
+ c = komeda_component_add(&d71->pipes[blk_id]->base, sizeof(*ctrlr),
+ KOMEDA_COMPONENT_TIMING_CTRLR,
+ BLOCK_INFO_INPUT_ID(blk->block_info),
+ &d71_timing_ctrlr_funcs,
+ 1, BIT(KOMEDA_COMPONENT_IPS0 + blk_id),
+ BS_NUM_OUTPUT_IDS, reg, "DOU%d_BS", blk_id);
+ if (!c) {
+ DRM_ERROR("Failed to add display_ctrl component\n");
+ return -EINVAL;
+ }
+
+ ctrlr = to_ctrlr(c);
+
+ ctrlr->supports_dual_link = true;
return 0;
}
@@ -11,6 +11,8 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_writeback.h>
+#include <video/videomode.h>
+#include <video/display_timing.h>
/** struct komeda_plane - komeda instance of drm_plane */
struct komeda_plane {
@@ -258,15 +258,22 @@ struct komeda_compiz_state {
struct komeda_improc {
struct komeda_component base;
+ u32 supported_color_formats; /* DRM_RGB/YUV444/YUV420*/
+ u32 supported_color_depths; /* BIT(8) | BIT(10)*/
+ u8 supports_degamma : 1;
+ u8 supports_csc : 1;
+ u8 supports_gamma : 1;
};
struct komeda_improc_state {
struct komeda_component_state base;
+ u16 hsize, vsize;
};
/* display timing controller */
struct komeda_timing_ctrlr {
struct komeda_component base;
+ u8 supports_dual_link : 1;
};
struct komeda_timing_ctrlr_state {
Add and initialize improc and timing_ctrlr according to D71 capablitites Signed-off-by: James (Qian) Wang <james.qian.wang@arm.com> --- .../arm/display/komeda/d71/d71_component.c | 108 +++++++++++++++++- .../gpu/drm/arm/display/komeda/komeda_kms.h | 2 + .../drm/arm/display/komeda/komeda_pipeline.h | 7 ++ 3 files changed, 115 insertions(+), 2 deletions(-)