#include "komeda_kms.h"
#include "malidp_io.h"
#include "komeda_framebuffer.h"
+#include "komeda_color_mgmt.h"
static void get_resources_id(u32 hw_id, u32 *pipe_id, u32 *comp_id)
{
return comp ? (comp->hw_id + output->output_port) : 0;
}
+static void d71_layer_update_fb(struct komeda_component *c,
+ struct komeda_fb *kfb,
+ dma_addr_t *addr)
+{
+ struct drm_framebuffer *fb = &kfb->base;
+ const struct drm_format_info *info = fb->format;
+ u32 __iomem *reg = c->reg;
+ int block_h;
+
+ if (info->num_planes > 2)
+ malidp_write64(reg, BLK_P2_PTR_LOW, addr[2]);
+
+ if (info->num_planes > 1) {
+ block_h = drm_format_info_block_height(info, 1);
+ malidp_write32(reg, BLK_P1_STRIDE, fb->pitches[1] * block_h);
+ malidp_write64(reg, BLK_P1_PTR_LOW, addr[1]);
+ }
+
+ block_h = drm_format_info_block_height(info, 0);
+ malidp_write32(reg, BLK_P0_STRIDE, fb->pitches[0] * block_h);
+ malidp_write64(reg, BLK_P0_PTR_LOW, addr[0]);
+ malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
+}
+
static void d71_layer_disable(struct komeda_component *c)
{
malidp_write32_mask(c->reg, BLK_CONTROL, L_EN, 0);
u32 __iomem *reg = c->reg;
u32 ctrl_mask = L_EN | L_ROT(L_ROT_R270) | L_HFLIP | L_VFLIP | L_TBU_EN;
u32 ctrl = L_EN | to_rot_ctrl(st->rot);
- int i;
-
- for (i = 0; i < fb->format->num_planes; i++) {
- malidp_write32(reg,
- BLK_P0_PTR_LOW + i * LAYER_PER_PLANE_REGS * 4,
- lower_32_bits(st->addr[i]));
- malidp_write32(reg,
- BLK_P0_PTR_HIGH + i * LAYER_PER_PLANE_REGS * 4,
- upper_32_bits(st->addr[i]));
- if (i >= 2)
- break;
- malidp_write32(reg,
- BLK_P0_STRIDE + i * LAYER_PER_PLANE_REGS * 4,
- fb->pitches[i] & 0xFFFF);
- }
+ d71_layer_update_fb(c, kfb, st->addr);
malidp_write32(reg, AD_CONTROL, to_ad_ctrl(fb->modifier));
if (fb->modifier) {
malidp_write32(reg, BLK_P1_PTR_HIGH, upper_32_bits(addr));
}
- malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
+ if (fb->format->is_yuv) {
+ u32 upsampling = 0;
+
+ switch (kfb->format_caps->fourcc) {
+ case DRM_FORMAT_YUYV:
+ upsampling = fb->modifier ? LR_CHI422_BILINEAR :
+ LR_CHI422_REPLICATION;
+ break;
+ case DRM_FORMAT_UYVY:
+ upsampling = LR_CHI422_REPLICATION;
+ break;
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_YUV420_8BIT:
+ case DRM_FORMAT_YUV420_10BIT:
+ case DRM_FORMAT_YUV420:
+ case DRM_FORMAT_P010:
+ /* these fmt support MPGE/JPEG both, here perfer JPEG*/
+ upsampling = LR_CHI420_JPEG;
+ break;
+ case DRM_FORMAT_X0L2:
+ upsampling = LR_CHI420_JPEG;
+ break;
+ default:
+ break;
+ }
+
+ malidp_write32(reg, LAYER_R_CONTROL, upsampling);
+ malidp_write_group(reg, LAYER_YUV_RGB_COEFF0,
+ KOMEDA_N_YUV2RGB_COEFFS,
+ komeda_select_yuv2rgb_coeffs(
+ plane_st->color_encoding,
+ plane_st->color_range));
+ }
+
malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
+ if (kfb->is_va)
+ ctrl |= L_TBU_EN;
malidp_write32_mask(reg, BLK_CONTROL, ctrl_mask, ctrl);
}
{
struct komeda_layer_state *st = to_layer_st(state);
struct drm_connector_state *conn_st = state->wb_conn->state;
- struct drm_framebuffer *fb = conn_st->writeback_job->fb;
- struct komeda_fb *kfb = to_kfb(fb);
- u32 __iomem *reg = c->reg;
+ struct komeda_fb *kfb = to_kfb(conn_st->writeback_job->fb);
u32 ctrl = L_EN | LW_OFM, mask = L_EN | LW_OFM | LW_TBU_EN;
- int i;
+ u32 __iomem *reg = c->reg;
- for (i = 0; i < fb->format->num_planes; i++) {
- malidp_write32(reg + i * LAYER_PER_PLANE_REGS, BLK_P0_PTR_LOW,
- lower_32_bits(st->addr[i]));
- malidp_write32(reg + i * LAYER_PER_PLANE_REGS, BLK_P0_PTR_HIGH,
- upper_32_bits(st->addr[i]));
+ d71_layer_update_fb(c, kfb, st->addr);
- malidp_write32(reg + i * LAYER_PER_PLANE_REGS, BLK_P0_STRIDE,
- fb->pitches[i] & 0xFFFF);
- }
+ if (kfb->is_va)
+ ctrl |= LW_TBU_EN;
- malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id);
malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize));
malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(&state->inputs[0]));
malidp_write32_mask(reg, BLK_CONTROL, mask, ctrl);
malidp_write32(reg, BLK_CONTROL, 0);
- for (i = 0; i < c->max_active_inputs; i++)
+ for (i = 0; i < c->max_active_inputs; i++) {
malidp_write32(reg, BLK_INPUT_ID0 + (i << 2), 0);
+
+ /* Besides clearing the input ID to zero, D71 compiz also has
+ * input enable bit in CU_INPUTx_CONTROL which need to be
+ * cleared.
+ */
+ if (has_bit(c->id, KOMEDA_PIPELINE_COMPIZS))
+ malidp_write32(reg, CU_INPUT0_CONTROL +
+ i * CU_PER_INPUT_REGS * 4,
+ CU_INPUT_CTRL_ALPHA(0xFF));
+ }
}
static void compiz_enable_input(u32 __iomem *id_reg,
ctrl = 0;
ctrl |= st->en_scaling ? SC_CTRL_SCL : 0;
ctrl |= st->en_alpha ? SC_CTRL_AP : 0;
+ ctrl |= st->en_img_enhancement ? SC_CTRL_IENH : 0;
malidp_write32(reg, BLK_CONTROL, ctrl);
malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(&state->inputs[0]));
static int d71_downscaling_clk_check(struct komeda_pipeline *pipe,
struct drm_display_mode *mode,
- unsigned long mclk_rate,
+ unsigned long aclk_rate,
struct komeda_data_flow_cfg *dflow)
{
u32 h_in = dflow->in_w;
/* D71 downscaling must satisfy the following equation
*
- * MCLK h_in * v_in
+ * ACLK h_in * v_in
* ------- >= ---------------------------------------------
* PXLCLK (h_total - (1 + 2 * v_in / v_out)) * v_out
*
* In only horizontal downscaling situation, the right side should be
* multiplied by (h_total - 3) / (h_active - 3), then equation becomes
*
- * MCLK h_in
+ * ACLK h_in
* ------- >= ----------------
* PXLCLK (h_active - 3)
*
* To avoid precision lost the equation 1 will be convert to:
*
- * MCLK h_in * v_in
+ * ACLK h_in * v_in
* ------- >= -----------------------------------
* PXLCLK (h_total -1 ) * v_out - 2 * v_in
*/
denominator = (mode->htotal - 1) * v_out - 2 * v_in;
}
- return mclk_rate * denominator >= mode->clock * 1000 * fraction ?
+ return aclk_rate * denominator >= mode->clock * 1000 * fraction ?
0 : -EINVAL;
}