1 /*
2 * Copyright (c) 2015-2016 MediaTek Inc.
3 * Author: Houlong Wei <houlong.wei@mediatek.com>
4 * Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16 #include <linux/platform_device.h>
17
18 #include "mtk_mdp_core.h"
19 #include "mtk_mdp_regs.h"
20
21
22 #define MDP_COLORFMT_PACK(VIDEO, PLANE, COPLANE, HF, VF, BITS, GROUP, SWAP, ID)\
23 (((VIDEO) << 27) | ((PLANE) << 24) | ((COPLANE) << 22) |\
24 ((HF) << 20) | ((VF) << 18) | ((BITS) << 8) | ((GROUP) << 6) |\
25 ((SWAP) << 5) | ((ID) << 0))
26
27 enum MDP_COLOR_ENUM {
28 MDP_COLOR_UNKNOWN = 0,
29 MDP_COLOR_NV12 = MDP_COLORFMT_PACK(0, 2, 1, 1, 1, 8, 1, 0, 12),
30 MDP_COLOR_I420 = MDP_COLORFMT_PACK(0, 3, 0, 1, 1, 8, 1, 0, 8),
31 MDP_COLOR_YV12 = MDP_COLORFMT_PACK(0, 3, 0, 1, 1, 8, 1, 1, 8),
32 /* Mediatek proprietary format */
33 MDP_COLOR_420_MT21 = MDP_COLORFMT_PACK(5, 2, 1, 1, 1, 256, 1, 0, 12),
34 };
35
mtk_mdp_map_color_format(int v4l2_format)36 static int32_t mtk_mdp_map_color_format(int v4l2_format)
37 {
38 switch (v4l2_format) {
39 case V4L2_PIX_FMT_NV12M:
40 case V4L2_PIX_FMT_NV12:
41 return MDP_COLOR_NV12;
42 case V4L2_PIX_FMT_MT21C:
43 return MDP_COLOR_420_MT21;
44 case V4L2_PIX_FMT_YUV420M:
45 case V4L2_PIX_FMT_YUV420:
46 return MDP_COLOR_I420;
47 case V4L2_PIX_FMT_YVU420:
48 return MDP_COLOR_YV12;
49 }
50
51 mtk_mdp_err("Unknown format 0x%x", v4l2_format);
52
53 return MDP_COLOR_UNKNOWN;
54 }
55
mtk_mdp_hw_set_input_addr(struct mtk_mdp_ctx * ctx,struct mtk_mdp_addr * addr)56 void mtk_mdp_hw_set_input_addr(struct mtk_mdp_ctx *ctx,
57 struct mtk_mdp_addr *addr)
58 {
59 struct mdp_buffer *src_buf = &ctx->vpu.vsi->src_buffer;
60 int i;
61
62 for (i = 0; i < ARRAY_SIZE(addr->addr); i++)
63 src_buf->addr_mva[i] = (uint64_t)addr->addr[i];
64 }
65
mtk_mdp_hw_set_output_addr(struct mtk_mdp_ctx * ctx,struct mtk_mdp_addr * addr)66 void mtk_mdp_hw_set_output_addr(struct mtk_mdp_ctx *ctx,
67 struct mtk_mdp_addr *addr)
68 {
69 struct mdp_buffer *dst_buf = &ctx->vpu.vsi->dst_buffer;
70 int i;
71
72 for (i = 0; i < ARRAY_SIZE(addr->addr); i++)
73 dst_buf->addr_mva[i] = (uint64_t)addr->addr[i];
74 }
75
mtk_mdp_hw_set_in_size(struct mtk_mdp_ctx * ctx)76 void mtk_mdp_hw_set_in_size(struct mtk_mdp_ctx *ctx)
77 {
78 struct mtk_mdp_frame *frame = &ctx->s_frame;
79 struct mdp_config *config = &ctx->vpu.vsi->src_config;
80
81 /* Set input pixel offset */
82 config->crop_x = frame->crop.left;
83 config->crop_y = frame->crop.top;
84
85 /* Set input cropped size */
86 config->crop_w = frame->crop.width;
87 config->crop_h = frame->crop.height;
88
89 /* Set input original size */
90 config->x = 0;
91 config->y = 0;
92 config->w = frame->width;
93 config->h = frame->height;
94 }
95
mtk_mdp_hw_set_in_image_format(struct mtk_mdp_ctx * ctx)96 void mtk_mdp_hw_set_in_image_format(struct mtk_mdp_ctx *ctx)
97 {
98 unsigned int i;
99 struct mtk_mdp_frame *frame = &ctx->s_frame;
100 struct mdp_config *config = &ctx->vpu.vsi->src_config;
101 struct mdp_buffer *src_buf = &ctx->vpu.vsi->src_buffer;
102
103 src_buf->plane_num = frame->fmt->num_comp;
104 config->format = mtk_mdp_map_color_format(frame->fmt->pixelformat);
105 config->w_stride = 0; /* MDP will calculate it by color format. */
106 config->h_stride = 0; /* MDP will calculate it by color format. */
107
108 for (i = 0; i < src_buf->plane_num; i++)
109 src_buf->plane_size[i] = frame->payload[i];
110 }
111
mtk_mdp_hw_set_out_size(struct mtk_mdp_ctx * ctx)112 void mtk_mdp_hw_set_out_size(struct mtk_mdp_ctx *ctx)
113 {
114 struct mtk_mdp_frame *frame = &ctx->d_frame;
115 struct mdp_config *config = &ctx->vpu.vsi->dst_config;
116
117 config->crop_x = frame->crop.left;
118 config->crop_y = frame->crop.top;
119 config->crop_w = frame->crop.width;
120 config->crop_h = frame->crop.height;
121 config->x = 0;
122 config->y = 0;
123 config->w = frame->width;
124 config->h = frame->height;
125 }
126
mtk_mdp_hw_set_out_image_format(struct mtk_mdp_ctx * ctx)127 void mtk_mdp_hw_set_out_image_format(struct mtk_mdp_ctx *ctx)
128 {
129 unsigned int i;
130 struct mtk_mdp_frame *frame = &ctx->d_frame;
131 struct mdp_config *config = &ctx->vpu.vsi->dst_config;
132 struct mdp_buffer *dst_buf = &ctx->vpu.vsi->dst_buffer;
133
134 dst_buf->plane_num = frame->fmt->num_comp;
135 config->format = mtk_mdp_map_color_format(frame->fmt->pixelformat);
136 config->w_stride = 0; /* MDP will calculate it by color format. */
137 config->h_stride = 0; /* MDP will calculate it by color format. */
138 for (i = 0; i < dst_buf->plane_num; i++)
139 dst_buf->plane_size[i] = frame->payload[i];
140 }
141
mtk_mdp_hw_set_rotation(struct mtk_mdp_ctx * ctx)142 void mtk_mdp_hw_set_rotation(struct mtk_mdp_ctx *ctx)
143 {
144 struct mdp_config_misc *misc = &ctx->vpu.vsi->misc;
145
146 misc->orientation = ctx->ctrls.rotate->val;
147 misc->hflip = ctx->ctrls.hflip->val;
148 misc->vflip = ctx->ctrls.vflip->val;
149 }
150
mtk_mdp_hw_set_global_alpha(struct mtk_mdp_ctx * ctx)151 void mtk_mdp_hw_set_global_alpha(struct mtk_mdp_ctx *ctx)
152 {
153 struct mdp_config_misc *misc = &ctx->vpu.vsi->misc;
154
155 misc->alpha = ctx->ctrls.global_alpha->val;
156 }
157