| /* |
| * Copyright (c) 2015-2016 MediaTek Inc. |
| * Author: Houlong Wei <houlong.wei@mediatek.com> |
| * Ming Hsiu Tsai <minghsiu.tsai@mediatek.com> |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 as |
| * published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| */ |
| |
| #include <linux/platform_device.h> |
| |
| #include "mtk_mdp_core.h" |
| #include "mtk_mdp_regs.h" |
| #include "mtk_mdp_type.h" |
| |
| static int32_t mtk_mdp_map_color_format(int v4l2_format) |
| { |
| switch (v4l2_format) { |
| case V4L2_PIX_FMT_NV12M: |
| case V4L2_PIX_FMT_NV12: |
| return DP_COLOR_NV12; |
| case V4L2_PIX_FMT_NV21M: |
| case V4L2_PIX_FMT_NV21: |
| return DP_COLOR_NV21; |
| case V4L2_PIX_FMT_MT21C: |
| return DP_COLOR_420_BLKP_UFO; |
| case V4L2_PIX_FMT_YUV420M: |
| case V4L2_PIX_FMT_YUV420: |
| return DP_COLOR_I420; |
| case V4L2_PIX_FMT_YVU420M: |
| case V4L2_PIX_FMT_YVU420: |
| return DP_COLOR_YV12; |
| case V4L2_PIX_FMT_YUV422P: |
| return DP_COLOR_I422; |
| case V4L2_PIX_FMT_NV16: |
| case V4L2_PIX_FMT_NV16M: |
| return DP_COLOR_NV16; |
| case V4L2_PIX_FMT_YUYV: |
| return DP_COLOR_YUYV; |
| case V4L2_PIX_FMT_UYVY: |
| return DP_COLOR_UYVY; |
| case V4L2_PIX_FMT_YVYU: |
| return DP_COLOR_YVYU; |
| case V4L2_PIX_FMT_VYUY: |
| return DP_COLOR_VYUY; |
| case V4L2_PIX_FMT_ARGB32: |
| return DP_COLOR_RGBA8888; |
| case V4L2_PIX_FMT_ABGR32: |
| return DP_COLOR_BGRA8888; |
| case V4L2_PIX_FMT_XRGB32: |
| return DP_COLOR_RGBA8888; |
| case V4L2_PIX_FMT_XBGR32: |
| return DP_COLOR_BGRA8888; |
| case V4L2_PIX_FMT_RGB565: |
| return DP_COLOR_RGB565; |
| case V4L2_PIX_FMT_RGB24: |
| return DP_COLOR_RGB888; |
| case V4L2_PIX_FMT_BGR24: |
| return DP_COLOR_BGR888; |
| } |
| |
| mtk_mdp_err("Unknown format 0x%x", v4l2_format); |
| |
| return DP_COLOR_UNKNOWN; |
| } |
| |
| void mtk_mdp_hw_set_input_addr(struct mtk_mdp_ctx *ctx, |
| struct mtk_mdp_addr *addr) |
| { |
| struct mdp_buffer *src_buf = &ctx->vpu.vsi->src_buffer; |
| int i; |
| |
| for (i = 0; i < ARRAY_SIZE(addr->addr); i++) |
| src_buf->addr_mva[i] = (uint64_t)addr->addr[i]; |
| } |
| |
| void mtk_mdp_hw_set_output_addr(struct mtk_mdp_ctx *ctx, |
| struct mtk_mdp_addr *addr) |
| { |
| struct mdp_buffer *dst_buf = &ctx->vpu.vsi->dst_buffer; |
| int i; |
| |
| for (i = 0; i < ARRAY_SIZE(addr->addr); i++) |
| dst_buf->addr_mva[i] = (uint64_t)addr->addr[i]; |
| } |
| |
| void mtk_mdp_hw_set_in_size(struct mtk_mdp_ctx *ctx) |
| { |
| struct mtk_mdp_frame *frame = &ctx->s_frame; |
| struct mdp_config *config = &ctx->vpu.vsi->src_config; |
| |
| /* Set input pixel offset */ |
| config->crop_x = frame->crop.left; |
| config->crop_y = frame->crop.top; |
| |
| /* Set input cropped size */ |
| config->crop_w = frame->crop.width; |
| config->crop_h = frame->crop.height; |
| |
| /* Set input original size */ |
| config->x = 0; |
| config->y = 0; |
| config->w = frame->width; |
| config->h = frame->height; |
| } |
| |
| void mtk_mdp_hw_set_in_image_format(struct mtk_mdp_ctx *ctx) |
| { |
| unsigned int i, num_comp; |
| struct mtk_mdp_frame *frame = &ctx->s_frame; |
| struct mdp_config *config = &ctx->vpu.vsi->src_config; |
| struct mdp_buffer *src_buf = &ctx->vpu.vsi->src_buffer; |
| |
| num_comp = frame->fmt->num_comp; |
| src_buf->plane_num = num_comp; |
| config->format = mtk_mdp_map_color_format(frame->fmt->pixelformat); |
| if (frame->fmt->num_planes == 1 && num_comp > 1) { |
| config->pitch[0] = frame->pitch[0]; |
| config->pitch[1] = frame->pitch[1]; |
| config->pitch[2] = frame->pitch[2]; |
| src_buf->plane_size[0] = |
| (int32_t)(frame->addr.addr[1] - frame->addr.addr[0]); |
| if (num_comp > 2) { |
| src_buf->plane_size[1] = |
| (int32_t)(frame->addr.addr[2] - |
| frame->addr.addr[1]); |
| src_buf->plane_size[2] = frame->payload[0] - |
| src_buf->plane_size[0] - |
| src_buf->plane_size[1]; |
| } else |
| src_buf->plane_size[1] = frame->payload[0] - |
| src_buf->plane_size[0]; |
| } else { |
| for (i = 0; i < src_buf->plane_num; i++) { |
| config->pitch[i] = frame->pitch[i]; |
| src_buf->plane_size[i] = (int32_t)frame->payload[i]; |
| } |
| } |
| } |
| |
| void mtk_mdp_hw_set_out_size(struct mtk_mdp_ctx *ctx) |
| { |
| struct mtk_mdp_frame *frame = &ctx->d_frame; |
| struct mdp_config *config = &ctx->vpu.vsi->dst_config; |
| |
| config->crop_x = frame->crop.left; |
| config->crop_y = frame->crop.top; |
| config->crop_w = frame->crop.width; |
| config->crop_h = frame->crop.height; |
| config->x = 0; |
| config->y = 0; |
| config->w = frame->width; |
| config->h = frame->height; |
| } |
| |
| void mtk_mdp_hw_set_out_image_format(struct mtk_mdp_ctx *ctx) |
| { |
| unsigned int i, num_comp; |
| struct mtk_mdp_frame *frame = &ctx->d_frame; |
| struct mdp_config *config = &ctx->vpu.vsi->dst_config; |
| struct mdp_buffer *dst_buf = &ctx->vpu.vsi->dst_buffer; |
| |
| num_comp = frame->fmt->num_comp; |
| dst_buf->plane_num = num_comp; |
| config->format = mtk_mdp_map_color_format(frame->fmt->pixelformat); |
| if (frame->fmt->num_planes == 1 && num_comp > 1) { |
| config->pitch[0] = frame->pitch[0]; |
| config->pitch[1] = frame->pitch[1]; |
| config->pitch[2] = frame->pitch[2]; |
| dst_buf->plane_size[0] = |
| (int32_t)(frame->addr.addr[1] - frame->addr.addr[0]); |
| if (num_comp > 2) { |
| dst_buf->plane_size[1] = |
| (int32_t)(frame->addr.addr[2] - |
| frame->addr.addr[1]); |
| dst_buf->plane_size[2] = frame->payload[0] - |
| dst_buf->plane_size[0] - |
| dst_buf->plane_size[1]; |
| } else |
| dst_buf->plane_size[1] = frame->payload[0] - |
| dst_buf->plane_size[0]; |
| } else { |
| for (i = 0; i < dst_buf->plane_num; i++) { |
| config->pitch[i] = frame->pitch[i]; |
| dst_buf->plane_size[i] = (int32_t)frame->payload[i]; |
| } |
| } |
| } |
| |
| void mtk_mdp_hw_set_rotation(struct mtk_mdp_ctx *ctx) |
| { |
| struct mdp_config_misc *misc = &ctx->vpu.vsi->misc; |
| |
| misc->orientation = ctx->ctrls.rotate->val; |
| misc->hflip = ctx->ctrls.hflip->val; |
| misc->vflip = ctx->ctrls.vflip->val; |
| } |
| |
| void mtk_mdp_hw_set_global_alpha(struct mtk_mdp_ctx *ctx) |
| { |
| struct mdp_config_misc *misc = &ctx->vpu.vsi->misc; |
| |
| misc->alpha = ctx->ctrls.global_alpha->val; |
| } |
| |
| void mtk_mdp_hw_set_pq_info(struct mtk_mdp_ctx *ctx) |
| { |
| struct mdp_pq_info *vsi_pq = &ctx->vpu.vsi->pq; |
| |
| vsi_pq->sharpness_enable = !!ctx->sharpness; |
| vsi_pq->sharpness_level = ctx->sharpness; |
| vsi_pq->dynamic_contrast_enable = ctx->contrast_auto; |
| } |