13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/types.h>
16 #include <linux/errno.h>
20 #include <linux/device.h>
22 #include <linux/list.h>
24 #include <linux/slab.h>
31 #define GSC_CLOCK_GATE_NAME "gscl"
33 static const struct gsc_fmt gsc_formats[] = {
42 .name =
"XRGB-8-8-8-8, 32 bpp",
49 .name =
"YUV 4:2:2 packed, YCbYCr",
59 .name =
"YUV 4:2:2 packed, CbYCrY",
69 .name =
"YUV 4:2:2 packed, CrYCbY",
79 .name =
"YUV 4:2:2 packed, YCrYCb",
89 .name =
"YUV 4:4:4 planar, YCbYCr",
98 .name =
"YUV 4:2:2 planar, Y/Cb/Cr",
107 .name =
"YUV 4:2:2 planar, Y/CbCr",
116 .name =
"YUV 4:2:2 planar, Y/CrCb",
125 .name =
"YUV 4:2:0 planar, YCbCr",
134 .name =
"YUV 4:2:0 planar, YCrCb",
144 .name =
"YUV 4:2:0 planar, Y/CbCr",
153 .name =
"YUV 4:2:0 planar, Y/CrCb",
162 .name =
"YUV 4:2:0 non-contig. 2p, Y/CbCr",
171 .name =
"YUV 4:2:0 non-contig. 3p, Y/Cb/Cr",
173 .depth = { 8, 2, 2 },
180 .name =
"YUV 4:2:0 non-contig. 3p, Y/Cr/Cb",
182 .depth = { 8, 2, 2 },
209 if (pixelformat && fmt->
pixelformat == *pixelformat)
211 if (mbus_code && fmt->
mbus_code == *mbus_code)
226 frame->
crop.left = 0;
239 pr_err(
"Exceeded maximum downscaling ratio (1/16))");
243 *ratio = (dst > (src / 8)) ? 2 : 4;
250 if (hratio == 4 && vratio == 4)
252 else if ((hratio == 4 && vratio == 2) ||
253 (hratio == 2 && vratio == 4))
255 else if ((hratio == 4 && vratio == 1) ||
256 (hratio == 1 && vratio == 4) ||
257 (hratio == 2 && vratio == 2))
259 else if (hratio == 1 && vratio == 1)
269 int remainder = 0, walign, halign;
282 remainder = s_frame->
crop.width % (*wratio * walign);
284 s_frame->
crop.width -= remainder;
286 pr_info(
"cropped src width size is recalculated from %d to %d",
287 s_frame->
crop.width + remainder, s_frame->
crop.width);
290 remainder = s_frame->
crop.height % (*hratio * halign);
292 s_frame->
crop.height -= remainder;
294 pr_info(
"cropped src height size is recalculated from %d to %d",
295 s_frame->
crop.height + remainder, s_frame->
crop.height);
315 if (frm->
addr.y == addr) {
318 }
else if (frm->
addr.cb == addr) {
321 }
else if (frm->
addr.cr == addr) {
325 pr_err(
"Plane address is wrong");
332 u32 f_chk_addr, f_chk_len, s_chk_addr, s_chk_len;
333 f_chk_addr = f_chk_len = s_chk_addr = s_chk_len = 0;
335 f_chk_addr = frm->
addr.y;
337 if (frm->
fmt->num_planes == 2) {
338 s_chk_addr = frm->
addr.cb;
340 }
else if (frm->
fmt->num_planes == 3) {
341 u32 low_addr, low_plane, mid_addr, mid_plane;
342 u32 high_addr, high_plane;
346 low_addr = get_plane_info(frm, t_min, &low_plane);
348 high_addr = get_plane_info(frm, t_max, &high_plane);
350 mid_plane = 3 - (low_plane + high_plane);
352 mid_addr = frm->
addr.y;
353 else if (mid_plane == 1)
354 mid_addr = frm->
addr.cb;
355 else if (mid_plane == 2)
356 mid_addr = frm->
addr.cr;
360 f_chk_addr = low_addr;
361 if (mid_addr + frm->
payload[mid_plane] - low_addr >
362 high_addr + frm->
payload[high_plane] - mid_addr) {
363 f_chk_len = frm->
payload[low_plane];
364 s_chk_addr = mid_addr;
365 s_chk_len = high_addr +
366 frm->
payload[high_plane] - mid_addr;
368 f_chk_len = mid_addr +
369 frm->
payload[mid_plane] - low_addr;
370 s_chk_addr = high_addr;
371 s_chk_len = frm->
payload[high_plane];
374 pr_debug(
"f_addr = 0x%08x, f_len = %d, s_addr = 0x%08x, s_len = %d\n",
375 f_chk_addr, f_chk_len, s_chk_addr, s_chk_len);
384 u32 max_w, max_h, mod_x, mod_y;
385 u32 min_w, min_h, tmp_w, tmp_h;
392 pr_err(
"pixelformat format (0x%X) invalid\n",
400 pr_err(
"Not supported field order(%d)\n", pix_mp->
field);
404 max_w = variant->
pix_max->target_rot_dis_w;
405 max_h = variant->
pix_max->target_rot_dis_h;
414 min_w = variant->
pix_min->org_w;
415 min_h = variant->
pix_min->org_h;
417 min_w = variant->
pix_min->target_rot_dis_w;
418 min_h = variant->
pix_min->target_rot_dis_h;
421 pr_debug(
"mod_x: %d, mod_y: %d, max_w: %d, max_h = %d",
422 mod_x, mod_y, max_w, max_h);
426 tmp_w = pix_mp->
width;
430 &pix_mp->
height, min_h, max_h, mod_y, 0);
431 if (tmp_w != pix_mp->
width || tmp_h != pix_mp->
height)
432 pr_info(
"Image size has been modified from %dx%d to %dx%d",
437 if (pix_mp->
width >= 1280)
448 pr_debug(
"[%d]: bpl: %d, sizeimage: %d",
461 frame = ctx_get_frame(ctx, f->
type);
463 return PTR_ERR(frame);
476 frame->
fmt->depth[
i]) / 8;
486 if (tmp_w != *w || tmp_h != *h) {
487 pr_info(
"Cropped size has been modified from %dx%d to %dx%d",
488 *w, *h, tmp_w, tmp_h);
498 frame = ctx_get_frame(ctx, cr->
type);
500 return PTR_ERR(frame);
512 u32 mod_x = 0, mod_y = 0, tmp_w, tmp_h;
513 u32 min_w, min_h, max_w, max_h;
515 if (cr->
c.top < 0 || cr->
c.left < 0) {
516 pr_err(
"doesn't support negative values for top & left\n");
519 pr_debug(
"user put w: %d, h: %d", cr->
c.width, cr->
c.height);
531 tmp_h = cr->
c.height;
553 min_w = variant->
pix_min->target_rot_en_w;
554 min_h = variant->
pix_min->target_rot_en_h;
555 tmp_w = cr->
c.height;
558 min_w = variant->
pix_min->target_rot_dis_w;
559 min_h = variant->
pix_min->target_rot_dis_h;
562 pr_debug(
"mod_x: %d, mod_y: %d, min_w: %d, min_h = %d",
563 mod_x, mod_y, min_w, min_h);
564 pr_debug(
"tmp_w : %d, tmp_h : %d", tmp_w, tmp_h);
567 &tmp_h, min_h, max_h, mod_y, 0);
573 &cr->
c.width, &cr->
c.height);
576 &cr->
c.width, &cr->
c.height);
581 if (cr->
c.left + tmp_w > max_w)
582 cr->
c.left = max_w - tmp_w;
583 if (cr->
c.top + tmp_h > max_h)
584 cr->
c.top = max_h - tmp_h;
590 pr_debug(
"Aligned l:%d, t:%d, w:%d, h:%d, f_w: %d, f_h: %d",
591 cr->
c.left, cr->
c.top, cr->
c.width, cr->
c.height, max_w, max_h);
597 int dh,
int rot,
int out_path)
606 if (rot == 90 || rot == 270) {
614 if ((sw / tmp_w) > sc_down_max ||
615 (sh / tmp_h) > sc_down_max ||
634 s_frame->
crop.height, d_frame->
crop.width, d_frame->
crop.height,
637 pr_err(
"out of scaler range");
643 ty = d_frame->
crop.width;
644 tx = d_frame->
crop.height;
646 tx = d_frame->
crop.width;
647 ty = d_frame->
crop.height;
650 if (tx <= 0 || ty <= 0) {
651 dev_err(dev,
"Invalid target size: %dx%d", tx, ty);
658 pr_err(
"Horizontal scale ratio is out of range");
665 pr_err(
"Vertical scale ratio is out of range");
678 pr_debug(
"scaler input/output size : sx = %d, sy = %d, tx = %d, ty = %d",
679 s_frame->
crop.width, s_frame->
crop.height, tx, ty);
680 pr_debug(
"scaler ratio info : pre_shfactor : %d, pre_h : %d",
682 pr_debug(
"pre_v :%d, main_h : %d, main_v : %d",
708 if ((ctx->
state & flags) == flags) {
733 static int gsc_s_ctrl(
struct v4l2_ctrl *ctrl)
740 ret = __gsc_s_ctrl(ctx, ctrl);
741 spin_unlock_irqrestore(&ctx->
gsc_dev->slock, flags);
747 .s_ctrl = gsc_s_ctrl,
753 pr_err(
"Control handler of this context was created already");
773 pr_err(
"Failed to create G-Scaler control handlers");
795 if ((vb ==
NULL) || (frame ==
NULL))
800 pr_debug(
"num_planes= %d, num_comp= %d, pix_size= %d",
801 frame->
fmt->num_planes, frame->
fmt->num_comp, pix_size);
803 addr->
y = vb2_dma_contig_plane_dma_addr(vb, 0);
805 if (frame->
fmt->num_planes == 1) {
806 switch (frame->
fmt->num_comp) {
827 pr_err(
"Invalid the number of color planes");
831 if (frame->
fmt->num_planes >= 2)
832 addr->
cb = vb2_dma_contig_plane_dma_addr(vb, 1);
834 if (frame->
fmt->num_planes == 3)
835 addr->
cr = vb2_dma_contig_plane_dma_addr(vb, 2);
846 pr_debug(
"ADDR: y= 0x%X cb= 0x%X cr= 0x%X ret= %d",
847 addr->
y, addr->
cb, addr->
cr, ret);
858 gsc_irq = gsc_hw_get_irq_status(gsc);
859 gsc_hw_clear_irq(gsc, gsc_irq);
862 pr_err(
"Local path input over-run interrupt has occurred!\n");
866 spin_lock(&gsc->
slock);
870 gsc_hw_enable_control(gsc,
false);
882 spin_unlock(&gsc->
slock);
894 spin_unlock(&gsc->
slock);
899 .org_scaler_bypass_w = 8192,
900 .org_scaler_bypass_h = 8192,
901 .org_scaler_input_w = 4800,
902 .org_scaler_input_h = 3344,
903 .real_rot_dis_w = 4800,
904 .real_rot_dis_h = 3344,
905 .real_rot_en_w = 2047,
906 .real_rot_en_h = 2047,
907 .target_rot_dis_w = 4800,
908 .target_rot_dis_h = 3344,
909 .target_rot_en_w = 2016,
910 .target_rot_en_h = 2016,
918 .target_rot_dis_w = 64,
919 .target_rot_dis_h = 32,
920 .target_rot_en_w = 32,
921 .target_rot_en_h = 16,
935 .pix_max = &gsc_v_100_max,
936 .pix_min = &gsc_v_100_min,
937 .pix_align = &gsc_v_100_align,
942 .poly_sc_down_max = 4,
943 .pre_sc_down_max = 4,
949 [0] = &gsc_v_100_variant,
950 [1] = &gsc_v_100_variant,
951 [2] = &gsc_v_100_variant,
952 [3] = &gsc_v_100_variant,
955 .lclk_frequency = 266000000
UL,
960 .name =
"exynos-gsc",
961 .driver_data = (
unsigned long)&gsc_v_100_drvdata,
969 .compatible =
"samsung,exynos5-gsc",
970 .data = &gsc_v_100_drvdata,
980 if (pdev->
dev.of_node) {
985 driver_data = match->
data;
994 static void gsc_clk_put(
struct gsc_dev *gsc)
996 if (IS_ERR_OR_NULL(gsc->
clock))
1004 static int gsc_clk_get(
struct gsc_dev *gsc)
1011 if (IS_ERR(gsc->
clock))
1024 dev_err(&gsc->
pdev->dev,
"clock prepare failed for clock: %s\n",
1028 dev_err(&gsc->
pdev->dev,
"failed to get clock~~~: %s\n",
1033 static int gsc_m2m_suspend(
struct gsc_dev *gsc)
1035 unsigned long flags;
1040 spin_unlock_irqrestore(&gsc->
slock, flags);
1045 spin_unlock_irqrestore(&gsc->
slock, flags);
1052 return timeout == 0 ? -
EAGAIN : 0;
1055 static int gsc_m2m_resume(
struct gsc_dev *gsc)
1057 unsigned long flags;
1062 spin_unlock_irqrestore(&gsc->
slock, flags);
1088 dev_err(dev,
"Invalid platform device id: %d\n", gsc->
id);
1103 dev_err(dev,
"failed to map registers\n");
1109 dev_err(dev,
"failed to get IRQ resource\n");
1113 ret = gsc_clk_get(gsc);
1117 ret = devm_request_irq(dev, res->
start, gsc_irq_handler,
1118 0, pdev->
name, gsc);
1120 dev_err(dev,
"failed to install irq (%d)\n", ret);
1128 platform_set_drvdata(pdev, gsc);
1130 ret = pm_runtime_get_sync(&pdev->
dev);
1141 dev_dbg(dev,
"gsc-%d registered successfully\n", gsc->
id);
1143 pm_runtime_put(dev);
1146 pm_runtime_put(dev);
1156 struct gsc_dev *gsc = platform_get_drvdata(pdev);
1161 pm_runtime_disable(&pdev->
dev);
1167 static int gsc_runtime_resume(
struct device *dev)
1181 return gsc_m2m_resume(gsc);
1184 static int gsc_runtime_suspend(
struct device *dev)
1189 ret = gsc_m2m_suspend(gsc);
1197 static int gsc_resume(
struct device *dev)
1200 unsigned long flags;
1208 spin_unlock_irqrestore(&gsc->
slock, flags);
1214 spin_unlock_irqrestore(&gsc->
slock, flags);
1216 return gsc_m2m_resume(gsc);
1219 static int gsc_suspend(
struct device *dev)
1228 return gsc_m2m_suspend(gsc);
1231 static const struct dev_pm_ops gsc_pm_ops = {
1232 .suspend = gsc_suspend,
1233 .resume = gsc_resume,
1234 .runtime_suspend = gsc_runtime_suspend,
1235 .runtime_resume = gsc_runtime_resume,
1241 .id_table = gsc_driver_ids,
1246 .of_match_table = exynos_gsc_match,