Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C) 2012 Samsung Electronics Co.Ltd
0004  * Authors:
0005  *  Eunchul Kim <chulspro.kim@samsung.com>
0006  *  Jinyoung Jeon <jy0.jeon@samsung.com>
0007  *  Sangmin Lee <lsmin.lee@samsung.com>
0008  */
0009 
0010 #include <linux/clk.h>
0011 #include <linux/component.h>
0012 #include <linux/kernel.h>
0013 #include <linux/mfd/syscon.h>
0014 #include <linux/of_device.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/pm_runtime.h>
0017 #include <linux/regmap.h>
0018 
0019 #include <drm/drm_fourcc.h>
0020 #include <drm/drm_print.h>
0021 #include <drm/exynos_drm.h>
0022 
0023 #include "exynos_drm_drv.h"
0024 #include "exynos_drm_ipp.h"
0025 #include "regs-gsc.h"
0026 
0027 /*
0028  * GSC stands for General SCaler and
0029  * supports image scaler/rotator and input/output DMA operations.
0030  * input DMA reads image data from the memory.
0031  * output DMA writes image data to memory.
0032  * GSC supports image rotation and image effect functions.
0033  */
0034 
0035 
0036 #define GSC_MAX_CLOCKS  8
0037 #define GSC_MAX_SRC     4
0038 #define GSC_MAX_DST     16
0039 #define GSC_RESET_TIMEOUT   50
0040 #define GSC_BUF_STOP    1
0041 #define GSC_BUF_START   2
0042 #define GSC_REG_SZ      16
0043 #define GSC_WIDTH_ITU_709   1280
0044 #define GSC_SC_UP_MAX_RATIO     65536
0045 #define GSC_SC_DOWN_RATIO_7_8       74898
0046 #define GSC_SC_DOWN_RATIO_6_8       87381
0047 #define GSC_SC_DOWN_RATIO_5_8       104857
0048 #define GSC_SC_DOWN_RATIO_4_8       131072
0049 #define GSC_SC_DOWN_RATIO_3_8       174762
0050 #define GSC_SC_DOWN_RATIO_2_8       262144
0051 #define GSC_CROP_MAX    8192
0052 #define GSC_CROP_MIN    32
0053 #define GSC_SCALE_MAX   4224
0054 #define GSC_SCALE_MIN   32
0055 #define GSC_COEF_RATIO  7
0056 #define GSC_COEF_PHASE  9
0057 #define GSC_COEF_ATTR   16
0058 #define GSC_COEF_H_8T   8
0059 #define GSC_COEF_V_4T   4
0060 #define GSC_COEF_DEPTH  3
0061 #define GSC_AUTOSUSPEND_DELAY       2000
0062 
0063 #define get_gsc_context(dev)    dev_get_drvdata(dev)
0064 #define gsc_read(offset)        readl(ctx->regs + (offset))
0065 #define gsc_write(cfg, offset)  writel(cfg, ctx->regs + (offset))
0066 
0067 /*
0068  * A structure of scaler.
0069  *
0070  * @range: narrow, wide.
0071  * @pre_shfactor: pre sclaer shift factor.
0072  * @pre_hratio: horizontal ratio of the prescaler.
0073  * @pre_vratio: vertical ratio of the prescaler.
0074  * @main_hratio: the main scaler's horizontal ratio.
0075  * @main_vratio: the main scaler's vertical ratio.
0076  */
0077 struct gsc_scaler {
0078     bool    range;
0079     u32 pre_shfactor;
0080     u32 pre_hratio;
0081     u32 pre_vratio;
0082     unsigned long main_hratio;
0083     unsigned long main_vratio;
0084 };
0085 
0086 /*
0087  * A structure of gsc context.
0088  *
0089  * @regs: memory mapped io registers.
0090  * @gsc_clk: gsc gate clock.
0091  * @sc: scaler infomations.
0092  * @id: gsc id.
0093  * @irq: irq number.
0094  * @rotation: supports rotation of src.
0095  */
0096 struct gsc_context {
0097     struct exynos_drm_ipp ipp;
0098     struct drm_device *drm_dev;
0099     void        *dma_priv;
0100     struct device   *dev;
0101     struct exynos_drm_ipp_task  *task;
0102     struct exynos_drm_ipp_formats   *formats;
0103     unsigned int            num_formats;
0104 
0105     void __iomem    *regs;
0106     const char  **clk_names;
0107     struct clk  *clocks[GSC_MAX_CLOCKS];
0108     int     num_clocks;
0109     struct gsc_scaler   sc;
0110     int id;
0111     int irq;
0112     bool    rotation;
0113 };
0114 
0115 /**
0116  * struct gsc_driverdata - per device type driver data for init time.
0117  *
0118  * @limits: picture size limits array
0119  * @num_limits: number of items in the aforementioned array
0120  * @clk_names: names of clocks needed by this variant
0121  * @num_clocks: the number of clocks needed by this variant
0122  */
0123 struct gsc_driverdata {
0124     const struct drm_exynos_ipp_limit *limits;
0125     int     num_limits;
0126     const char  *clk_names[GSC_MAX_CLOCKS];
0127     int     num_clocks;
0128 };
0129 
0130 /* 8-tap Filter Coefficient */
0131 static const int h_coef_8t[GSC_COEF_RATIO][GSC_COEF_ATTR][GSC_COEF_H_8T] = {
0132     {   /* Ratio <= 65536 (~8:8) */
0133         {  0,  0,   0, 128,   0,   0,  0,  0 },
0134         { -1,  2,  -6, 127,   7,  -2,  1,  0 },
0135         { -1,  4, -12, 125,  16,  -5,  1,  0 },
0136         { -1,  5, -15, 120,  25,  -8,  2,  0 },
0137         { -1,  6, -18, 114,  35, -10,  3, -1 },
0138         { -1,  6, -20, 107,  46, -13,  4, -1 },
0139         { -2,  7, -21,  99,  57, -16,  5, -1 },
0140         { -1,  6, -20,  89,  68, -18,  5, -1 },
0141         { -1,  6, -20,  79,  79, -20,  6, -1 },
0142         { -1,  5, -18,  68,  89, -20,  6, -1 },
0143         { -1,  5, -16,  57,  99, -21,  7, -2 },
0144         { -1,  4, -13,  46, 107, -20,  6, -1 },
0145         { -1,  3, -10,  35, 114, -18,  6, -1 },
0146         {  0,  2,  -8,  25, 120, -15,  5, -1 },
0147         {  0,  1,  -5,  16, 125, -12,  4, -1 },
0148         {  0,  1,  -2,   7, 127,  -6,  2, -1 }
0149     }, {    /* 65536 < Ratio <= 74898 (~8:7) */
0150         {  3, -8,  14, 111,  13,  -8,  3,  0 },
0151         {  2, -6,   7, 112,  21, -10,  3, -1 },
0152         {  2, -4,   1, 110,  28, -12,  4, -1 },
0153         {  1, -2,  -3, 106,  36, -13,  4, -1 },
0154         {  1, -1,  -7, 103,  44, -15,  4, -1 },
0155         {  1,  1, -11,  97,  53, -16,  4, -1 },
0156         {  0,  2, -13,  91,  61, -16,  4, -1 },
0157         {  0,  3, -15,  85,  69, -17,  4, -1 },
0158         {  0,  3, -16,  77,  77, -16,  3,  0 },
0159         { -1,  4, -17,  69,  85, -15,  3,  0 },
0160         { -1,  4, -16,  61,  91, -13,  2,  0 },
0161         { -1,  4, -16,  53,  97, -11,  1,  1 },
0162         { -1,  4, -15,  44, 103,  -7, -1,  1 },
0163         { -1,  4, -13,  36, 106,  -3, -2,  1 },
0164         { -1,  4, -12,  28, 110,   1, -4,  2 },
0165         { -1,  3, -10,  21, 112,   7, -6,  2 }
0166     }, {    /* 74898 < Ratio <= 87381 (~8:6) */
0167         { 2, -11,  25,  96, 25, -11,   2,  0 },
0168         { 2, -10,  19,  96, 31, -12,   2,  0 },
0169         { 2,  -9,  14,  94, 37, -12,   2,  0 },
0170         { 2,  -8,  10,  92, 43, -12,   1,  0 },
0171         { 2,  -7,   5,  90, 49, -12,   1,  0 },
0172         { 2,  -5,   1,  86, 55, -12,   0,  1 },
0173         { 2,  -4,  -2,  82, 61, -11,  -1,  1 },
0174         { 1,  -3,  -5,  77, 67,  -9,  -1,  1 },
0175         { 1,  -2,  -7,  72, 72,  -7,  -2,  1 },
0176         { 1,  -1,  -9,  67, 77,  -5,  -3,  1 },
0177         { 1,  -1, -11,  61, 82,  -2,  -4,  2 },
0178         { 1,   0, -12,  55, 86,   1,  -5,  2 },
0179         { 0,   1, -12,  49, 90,   5,  -7,  2 },
0180         { 0,   1, -12,  43, 92,  10,  -8,  2 },
0181         { 0,   2, -12,  37, 94,  14,  -9,  2 },
0182         { 0,   2, -12,  31, 96,  19, -10,  2 }
0183     }, {    /* 87381 < Ratio <= 104857 (~8:5) */
0184         { -1,  -8, 33,  80, 33,  -8,  -1,  0 },
0185         { -1,  -8, 28,  80, 37,  -7,  -2,  1 },
0186         {  0,  -8, 24,  79, 41,  -7,  -2,  1 },
0187         {  0,  -8, 20,  78, 46,  -6,  -3,  1 },
0188         {  0,  -8, 16,  76, 50,  -4,  -3,  1 },
0189         {  0,  -7, 13,  74, 54,  -3,  -4,  1 },
0190         {  1,  -7, 10,  71, 58,  -1,  -5,  1 },
0191         {  1,  -6,  6,  68, 62,   1,  -5,  1 },
0192         {  1,  -6,  4,  65, 65,   4,  -6,  1 },
0193         {  1,  -5,  1,  62, 68,   6,  -6,  1 },
0194         {  1,  -5, -1,  58, 71,  10,  -7,  1 },
0195         {  1,  -4, -3,  54, 74,  13,  -7,  0 },
0196         {  1,  -3, -4,  50, 76,  16,  -8,  0 },
0197         {  1,  -3, -6,  46, 78,  20,  -8,  0 },
0198         {  1,  -2, -7,  41, 79,  24,  -8,  0 },
0199         {  1,  -2, -7,  37, 80,  28,  -8, -1 }
0200     }, {    /* 104857 < Ratio <= 131072 (~8:4) */
0201         { -3,   0, 35,  64, 35,   0,  -3,  0 },
0202         { -3,  -1, 32,  64, 38,   1,  -3,  0 },
0203         { -2,  -2, 29,  63, 41,   2,  -3,  0 },
0204         { -2,  -3, 27,  63, 43,   4,  -4,  0 },
0205         { -2,  -3, 24,  61, 46,   6,  -4,  0 },
0206         { -2,  -3, 21,  60, 49,   7,  -4,  0 },
0207         { -1,  -4, 19,  59, 51,   9,  -4, -1 },
0208         { -1,  -4, 16,  57, 53,  12,  -4, -1 },
0209         { -1,  -4, 14,  55, 55,  14,  -4, -1 },
0210         { -1,  -4, 12,  53, 57,  16,  -4, -1 },
0211         { -1,  -4,  9,  51, 59,  19,  -4, -1 },
0212         {  0,  -4,  7,  49, 60,  21,  -3, -2 },
0213         {  0,  -4,  6,  46, 61,  24,  -3, -2 },
0214         {  0,  -4,  4,  43, 63,  27,  -3, -2 },
0215         {  0,  -3,  2,  41, 63,  29,  -2, -2 },
0216         {  0,  -3,  1,  38, 64,  32,  -1, -3 }
0217     }, {    /* 131072 < Ratio <= 174762 (~8:3) */
0218         { -1,   8, 33,  48, 33,   8,  -1,  0 },
0219         { -1,   7, 31,  49, 35,   9,  -1, -1 },
0220         { -1,   6, 30,  49, 36,  10,  -1, -1 },
0221         { -1,   5, 28,  48, 38,  12,  -1, -1 },
0222         { -1,   4, 26,  48, 39,  13,   0, -1 },
0223         { -1,   3, 24,  47, 41,  15,   0, -1 },
0224         { -1,   2, 23,  47, 42,  16,   0, -1 },
0225         { -1,   2, 21,  45, 43,  18,   1, -1 },
0226         { -1,   1, 19,  45, 45,  19,   1, -1 },
0227         { -1,   1, 18,  43, 45,  21,   2, -1 },
0228         { -1,   0, 16,  42, 47,  23,   2, -1 },
0229         { -1,   0, 15,  41, 47,  24,   3, -1 },
0230         { -1,   0, 13,  39, 48,  26,   4, -1 },
0231         { -1,  -1, 12,  38, 48,  28,   5, -1 },
0232         { -1,  -1, 10,  36, 49,  30,   6, -1 },
0233         { -1,  -1,  9,  35, 49,  31,   7, -1 }
0234     }, {    /* 174762 < Ratio <= 262144 (~8:2) */
0235         {  2,  13, 30,  38, 30,  13,   2,  0 },
0236         {  2,  12, 29,  38, 30,  14,   3,  0 },
0237         {  2,  11, 28,  38, 31,  15,   3,  0 },
0238         {  2,  10, 26,  38, 32,  16,   4,  0 },
0239         {  1,  10, 26,  37, 33,  17,   4,  0 },
0240         {  1,   9, 24,  37, 34,  18,   5,  0 },
0241         {  1,   8, 24,  37, 34,  19,   5,  0 },
0242         {  1,   7, 22,  36, 35,  20,   6,  1 },
0243         {  1,   6, 21,  36, 36,  21,   6,  1 },
0244         {  1,   6, 20,  35, 36,  22,   7,  1 },
0245         {  0,   5, 19,  34, 37,  24,   8,  1 },
0246         {  0,   5, 18,  34, 37,  24,   9,  1 },
0247         {  0,   4, 17,  33, 37,  26,  10,  1 },
0248         {  0,   4, 16,  32, 38,  26,  10,  2 },
0249         {  0,   3, 15,  31, 38,  28,  11,  2 },
0250         {  0,   3, 14,  30, 38,  29,  12,  2 }
0251     }
0252 };
0253 
0254 /* 4-tap Filter Coefficient */
0255 static const int v_coef_4t[GSC_COEF_RATIO][GSC_COEF_ATTR][GSC_COEF_V_4T] = {
0256     {   /* Ratio <= 65536 (~8:8) */
0257         {  0, 128,   0,  0 },
0258         { -4, 127,   5,  0 },
0259         { -6, 124,  11, -1 },
0260         { -8, 118,  19, -1 },
0261         { -8, 111,  27, -2 },
0262         { -8, 102,  37, -3 },
0263         { -8,  92,  48, -4 },
0264         { -7,  81,  59, -5 },
0265         { -6,  70,  70, -6 },
0266         { -5,  59,  81, -7 },
0267         { -4,  48,  92, -8 },
0268         { -3,  37, 102, -8 },
0269         { -2,  27, 111, -8 },
0270         { -1,  19, 118, -8 },
0271         { -1,  11, 124, -6 },
0272         {  0,   5, 127, -4 }
0273     }, {    /* 65536 < Ratio <= 74898 (~8:7) */
0274         {  8, 112,   8,  0 },
0275         {  4, 111,  14, -1 },
0276         {  1, 109,  20, -2 },
0277         { -2, 105,  27, -2 },
0278         { -3, 100,  34, -3 },
0279         { -5,  93,  43, -3 },
0280         { -5,  86,  51, -4 },
0281         { -5,  77,  60, -4 },
0282         { -5,  69,  69, -5 },
0283         { -4,  60,  77, -5 },
0284         { -4,  51,  86, -5 },
0285         { -3,  43,  93, -5 },
0286         { -3,  34, 100, -3 },
0287         { -2,  27, 105, -2 },
0288         { -2,  20, 109,  1 },
0289         { -1,  14, 111,  4 }
0290     }, {    /* 74898 < Ratio <= 87381 (~8:6) */
0291         { 16,  96,  16,  0 },
0292         { 12,  97,  21, -2 },
0293         {  8,  96,  26, -2 },
0294         {  5,  93,  32, -2 },
0295         {  2,  89,  39, -2 },
0296         {  0,  84,  46, -2 },
0297         { -1,  79,  53, -3 },
0298         { -2,  73,  59, -2 },
0299         { -2,  66,  66, -2 },
0300         { -2,  59,  73, -2 },
0301         { -3,  53,  79, -1 },
0302         { -2,  46,  84,  0 },
0303         { -2,  39,  89,  2 },
0304         { -2,  32,  93,  5 },
0305         { -2,  26,  96,  8 },
0306         { -2,  21,  97, 12 }
0307     }, {    /* 87381 < Ratio <= 104857 (~8:5) */
0308         { 22,  84,  22,  0 },
0309         { 18,  85,  26, -1 },
0310         { 14,  84,  31, -1 },
0311         { 11,  82,  36, -1 },
0312         {  8,  79,  42, -1 },
0313         {  6,  76,  47, -1 },
0314         {  4,  72,  52,  0 },
0315         {  2,  68,  58,  0 },
0316         {  1,  63,  63,  1 },
0317         {  0,  58,  68,  2 },
0318         {  0,  52,  72,  4 },
0319         { -1,  47,  76,  6 },
0320         { -1,  42,  79,  8 },
0321         { -1,  36,  82, 11 },
0322         { -1,  31,  84, 14 },
0323         { -1,  26,  85, 18 }
0324     }, {    /* 104857 < Ratio <= 131072 (~8:4) */
0325         { 26,  76,  26,  0 },
0326         { 22,  76,  30,  0 },
0327         { 19,  75,  34,  0 },
0328         { 16,  73,  38,  1 },
0329         { 13,  71,  43,  1 },
0330         { 10,  69,  47,  2 },
0331         {  8,  66,  51,  3 },
0332         {  6,  63,  55,  4 },
0333         {  5,  59,  59,  5 },
0334         {  4,  55,  63,  6 },
0335         {  3,  51,  66,  8 },
0336         {  2,  47,  69, 10 },
0337         {  1,  43,  71, 13 },
0338         {  1,  38,  73, 16 },
0339         {  0,  34,  75, 19 },
0340         {  0,  30,  76, 22 }
0341     }, {    /* 131072 < Ratio <= 174762 (~8:3) */
0342         { 29,  70,  29,  0 },
0343         { 26,  68,  32,  2 },
0344         { 23,  67,  36,  2 },
0345         { 20,  66,  39,  3 },
0346         { 17,  65,  43,  3 },
0347         { 15,  63,  46,  4 },
0348         { 12,  61,  50,  5 },
0349         { 10,  58,  53,  7 },
0350         {  8,  56,  56,  8 },
0351         {  7,  53,  58, 10 },
0352         {  5,  50,  61, 12 },
0353         {  4,  46,  63, 15 },
0354         {  3,  43,  65, 17 },
0355         {  3,  39,  66, 20 },
0356         {  2,  36,  67, 23 },
0357         {  2,  32,  68, 26 }
0358     }, {    /* 174762 < Ratio <= 262144 (~8:2) */
0359         { 32,  64,  32,  0 },
0360         { 28,  63,  34,  3 },
0361         { 25,  62,  37,  4 },
0362         { 22,  62,  40,  4 },
0363         { 19,  61,  43,  5 },
0364         { 17,  59,  46,  6 },
0365         { 15,  58,  48,  7 },
0366         { 13,  55,  51,  9 },
0367         { 11,  53,  53, 11 },
0368         {  9,  51,  55, 13 },
0369         {  7,  48,  58, 15 },
0370         {  6,  46,  59, 17 },
0371         {  5,  43,  61, 19 },
0372         {  4,  40,  62, 22 },
0373         {  4,  37,  62, 25 },
0374         {  3,  34,  63, 28 }
0375     }
0376 };
0377 
0378 static int gsc_sw_reset(struct gsc_context *ctx)
0379 {
0380     u32 cfg;
0381     int count = GSC_RESET_TIMEOUT;
0382 
0383     /* s/w reset */
0384     cfg = (GSC_SW_RESET_SRESET);
0385     gsc_write(cfg, GSC_SW_RESET);
0386 
0387     /* wait s/w reset complete */
0388     while (count--) {
0389         cfg = gsc_read(GSC_SW_RESET);
0390         if (!cfg)
0391             break;
0392         usleep_range(1000, 2000);
0393     }
0394 
0395     if (cfg) {
0396         DRM_DEV_ERROR(ctx->dev, "failed to reset gsc h/w.\n");
0397         return -EBUSY;
0398     }
0399 
0400     /* reset sequence */
0401     cfg = gsc_read(GSC_IN_BASE_ADDR_Y_MASK);
0402     cfg |= (GSC_IN_BASE_ADDR_MASK |
0403         GSC_IN_BASE_ADDR_PINGPONG(0));
0404     gsc_write(cfg, GSC_IN_BASE_ADDR_Y_MASK);
0405     gsc_write(cfg, GSC_IN_BASE_ADDR_CB_MASK);
0406     gsc_write(cfg, GSC_IN_BASE_ADDR_CR_MASK);
0407 
0408     cfg = gsc_read(GSC_OUT_BASE_ADDR_Y_MASK);
0409     cfg |= (GSC_OUT_BASE_ADDR_MASK |
0410         GSC_OUT_BASE_ADDR_PINGPONG(0));
0411     gsc_write(cfg, GSC_OUT_BASE_ADDR_Y_MASK);
0412     gsc_write(cfg, GSC_OUT_BASE_ADDR_CB_MASK);
0413     gsc_write(cfg, GSC_OUT_BASE_ADDR_CR_MASK);
0414 
0415     return 0;
0416 }
0417 
0418 static void gsc_handle_irq(struct gsc_context *ctx, bool enable,
0419         bool overflow, bool done)
0420 {
0421     u32 cfg;
0422 
0423     DRM_DEV_DEBUG_KMS(ctx->dev, "enable[%d]overflow[%d]level[%d]\n",
0424               enable, overflow, done);
0425 
0426     cfg = gsc_read(GSC_IRQ);
0427     cfg |= (GSC_IRQ_OR_MASK | GSC_IRQ_FRMDONE_MASK);
0428 
0429     if (enable)
0430         cfg |= GSC_IRQ_ENABLE;
0431     else
0432         cfg &= ~GSC_IRQ_ENABLE;
0433 
0434     if (overflow)
0435         cfg &= ~GSC_IRQ_OR_MASK;
0436     else
0437         cfg |= GSC_IRQ_OR_MASK;
0438 
0439     if (done)
0440         cfg &= ~GSC_IRQ_FRMDONE_MASK;
0441     else
0442         cfg |= GSC_IRQ_FRMDONE_MASK;
0443 
0444     gsc_write(cfg, GSC_IRQ);
0445 }
0446 
0447 
0448 static void gsc_src_set_fmt(struct gsc_context *ctx, u32 fmt, bool tiled)
0449 {
0450     u32 cfg;
0451 
0452     DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt);
0453 
0454     cfg = gsc_read(GSC_IN_CON);
0455     cfg &= ~(GSC_IN_RGB_TYPE_MASK | GSC_IN_YUV422_1P_ORDER_MASK |
0456          GSC_IN_CHROMA_ORDER_MASK | GSC_IN_FORMAT_MASK |
0457          GSC_IN_TILE_TYPE_MASK | GSC_IN_TILE_MODE |
0458          GSC_IN_CHROM_STRIDE_SEL_MASK | GSC_IN_RB_SWAP_MASK);
0459 
0460     switch (fmt) {
0461     case DRM_FORMAT_RGB565:
0462         cfg |= GSC_IN_RGB565;
0463         break;
0464     case DRM_FORMAT_XRGB8888:
0465     case DRM_FORMAT_ARGB8888:
0466         cfg |= GSC_IN_XRGB8888;
0467         break;
0468     case DRM_FORMAT_BGRX8888:
0469         cfg |= (GSC_IN_XRGB8888 | GSC_IN_RB_SWAP);
0470         break;
0471     case DRM_FORMAT_YUYV:
0472         cfg |= (GSC_IN_YUV422_1P |
0473             GSC_IN_YUV422_1P_ORDER_LSB_Y |
0474             GSC_IN_CHROMA_ORDER_CBCR);
0475         break;
0476     case DRM_FORMAT_YVYU:
0477         cfg |= (GSC_IN_YUV422_1P |
0478             GSC_IN_YUV422_1P_ORDER_LSB_Y |
0479             GSC_IN_CHROMA_ORDER_CRCB);
0480         break;
0481     case DRM_FORMAT_UYVY:
0482         cfg |= (GSC_IN_YUV422_1P |
0483             GSC_IN_YUV422_1P_OEDER_LSB_C |
0484             GSC_IN_CHROMA_ORDER_CBCR);
0485         break;
0486     case DRM_FORMAT_VYUY:
0487         cfg |= (GSC_IN_YUV422_1P |
0488             GSC_IN_YUV422_1P_OEDER_LSB_C |
0489             GSC_IN_CHROMA_ORDER_CRCB);
0490         break;
0491     case DRM_FORMAT_NV21:
0492         cfg |= (GSC_IN_CHROMA_ORDER_CRCB | GSC_IN_YUV420_2P);
0493         break;
0494     case DRM_FORMAT_NV61:
0495         cfg |= (GSC_IN_CHROMA_ORDER_CRCB | GSC_IN_YUV422_2P);
0496         break;
0497     case DRM_FORMAT_YUV422:
0498         cfg |= GSC_IN_YUV422_3P;
0499         break;
0500     case DRM_FORMAT_YUV420:
0501         cfg |= (GSC_IN_CHROMA_ORDER_CBCR | GSC_IN_YUV420_3P);
0502         break;
0503     case DRM_FORMAT_YVU420:
0504         cfg |= (GSC_IN_CHROMA_ORDER_CRCB | GSC_IN_YUV420_3P);
0505         break;
0506     case DRM_FORMAT_NV12:
0507         cfg |= (GSC_IN_CHROMA_ORDER_CBCR | GSC_IN_YUV420_2P);
0508         break;
0509     case DRM_FORMAT_NV16:
0510         cfg |= (GSC_IN_CHROMA_ORDER_CBCR | GSC_IN_YUV422_2P);
0511         break;
0512     }
0513 
0514     if (tiled)
0515         cfg |= (GSC_IN_TILE_C_16x8 | GSC_IN_TILE_MODE);
0516 
0517     gsc_write(cfg, GSC_IN_CON);
0518 }
0519 
0520 static void gsc_src_set_transf(struct gsc_context *ctx, unsigned int rotation)
0521 {
0522     unsigned int degree = rotation & DRM_MODE_ROTATE_MASK;
0523     u32 cfg;
0524 
0525     cfg = gsc_read(GSC_IN_CON);
0526     cfg &= ~GSC_IN_ROT_MASK;
0527 
0528     switch (degree) {
0529     case DRM_MODE_ROTATE_0:
0530         if (rotation & DRM_MODE_REFLECT_X)
0531             cfg |= GSC_IN_ROT_XFLIP;
0532         if (rotation & DRM_MODE_REFLECT_Y)
0533             cfg |= GSC_IN_ROT_YFLIP;
0534         break;
0535     case DRM_MODE_ROTATE_90:
0536         cfg |= GSC_IN_ROT_90;
0537         if (rotation & DRM_MODE_REFLECT_X)
0538             cfg |= GSC_IN_ROT_XFLIP;
0539         if (rotation & DRM_MODE_REFLECT_Y)
0540             cfg |= GSC_IN_ROT_YFLIP;
0541         break;
0542     case DRM_MODE_ROTATE_180:
0543         cfg |= GSC_IN_ROT_180;
0544         if (rotation & DRM_MODE_REFLECT_X)
0545             cfg &= ~GSC_IN_ROT_XFLIP;
0546         if (rotation & DRM_MODE_REFLECT_Y)
0547             cfg &= ~GSC_IN_ROT_YFLIP;
0548         break;
0549     case DRM_MODE_ROTATE_270:
0550         cfg |= GSC_IN_ROT_270;
0551         if (rotation & DRM_MODE_REFLECT_X)
0552             cfg &= ~GSC_IN_ROT_XFLIP;
0553         if (rotation & DRM_MODE_REFLECT_Y)
0554             cfg &= ~GSC_IN_ROT_YFLIP;
0555         break;
0556     }
0557 
0558     gsc_write(cfg, GSC_IN_CON);
0559 
0560     ctx->rotation = (cfg & GSC_IN_ROT_90) ? 1 : 0;
0561 }
0562 
0563 static void gsc_src_set_size(struct gsc_context *ctx,
0564                  struct exynos_drm_ipp_buffer *buf)
0565 {
0566     struct gsc_scaler *sc = &ctx->sc;
0567     u32 cfg;
0568 
0569     /* pixel offset */
0570     cfg = (GSC_SRCIMG_OFFSET_X(buf->rect.x) |
0571         GSC_SRCIMG_OFFSET_Y(buf->rect.y));
0572     gsc_write(cfg, GSC_SRCIMG_OFFSET);
0573 
0574     /* cropped size */
0575     cfg = (GSC_CROPPED_WIDTH(buf->rect.w) |
0576         GSC_CROPPED_HEIGHT(buf->rect.h));
0577     gsc_write(cfg, GSC_CROPPED_SIZE);
0578 
0579     /* original size */
0580     cfg = gsc_read(GSC_SRCIMG_SIZE);
0581     cfg &= ~(GSC_SRCIMG_HEIGHT_MASK |
0582         GSC_SRCIMG_WIDTH_MASK);
0583 
0584     cfg |= (GSC_SRCIMG_WIDTH(buf->buf.pitch[0] / buf->format->cpp[0]) |
0585         GSC_SRCIMG_HEIGHT(buf->buf.height));
0586 
0587     gsc_write(cfg, GSC_SRCIMG_SIZE);
0588 
0589     cfg = gsc_read(GSC_IN_CON);
0590     cfg &= ~GSC_IN_RGB_TYPE_MASK;
0591 
0592     if (buf->rect.w >= GSC_WIDTH_ITU_709)
0593         if (sc->range)
0594             cfg |= GSC_IN_RGB_HD_WIDE;
0595         else
0596             cfg |= GSC_IN_RGB_HD_NARROW;
0597     else
0598         if (sc->range)
0599             cfg |= GSC_IN_RGB_SD_WIDE;
0600         else
0601             cfg |= GSC_IN_RGB_SD_NARROW;
0602 
0603     gsc_write(cfg, GSC_IN_CON);
0604 }
0605 
0606 static void gsc_src_set_buf_seq(struct gsc_context *ctx, u32 buf_id,
0607                    bool enqueue)
0608 {
0609     bool masked = !enqueue;
0610     u32 cfg;
0611     u32 mask = 0x00000001 << buf_id;
0612 
0613     /* mask register set */
0614     cfg = gsc_read(GSC_IN_BASE_ADDR_Y_MASK);
0615 
0616     /* sequence id */
0617     cfg &= ~mask;
0618     cfg |= masked << buf_id;
0619     gsc_write(cfg, GSC_IN_BASE_ADDR_Y_MASK);
0620     gsc_write(cfg, GSC_IN_BASE_ADDR_CB_MASK);
0621     gsc_write(cfg, GSC_IN_BASE_ADDR_CR_MASK);
0622 }
0623 
0624 static void gsc_src_set_addr(struct gsc_context *ctx, u32 buf_id,
0625                 struct exynos_drm_ipp_buffer *buf)
0626 {
0627     /* address register set */
0628     gsc_write(buf->dma_addr[0], GSC_IN_BASE_ADDR_Y(buf_id));
0629     gsc_write(buf->dma_addr[1], GSC_IN_BASE_ADDR_CB(buf_id));
0630     gsc_write(buf->dma_addr[2], GSC_IN_BASE_ADDR_CR(buf_id));
0631 
0632     gsc_src_set_buf_seq(ctx, buf_id, true);
0633 }
0634 
0635 static void gsc_dst_set_fmt(struct gsc_context *ctx, u32 fmt, bool tiled)
0636 {
0637     u32 cfg;
0638 
0639     DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt);
0640 
0641     cfg = gsc_read(GSC_OUT_CON);
0642     cfg &= ~(GSC_OUT_RGB_TYPE_MASK | GSC_OUT_YUV422_1P_ORDER_MASK |
0643          GSC_OUT_CHROMA_ORDER_MASK | GSC_OUT_FORMAT_MASK |
0644          GSC_OUT_CHROM_STRIDE_SEL_MASK | GSC_OUT_RB_SWAP_MASK |
0645          GSC_OUT_GLOBAL_ALPHA_MASK);
0646 
0647     switch (fmt) {
0648     case DRM_FORMAT_RGB565:
0649         cfg |= GSC_OUT_RGB565;
0650         break;
0651     case DRM_FORMAT_ARGB8888:
0652     case DRM_FORMAT_XRGB8888:
0653         cfg |= (GSC_OUT_XRGB8888 | GSC_OUT_GLOBAL_ALPHA(0xff));
0654         break;
0655     case DRM_FORMAT_BGRX8888:
0656         cfg |= (GSC_OUT_XRGB8888 | GSC_OUT_RB_SWAP);
0657         break;
0658     case DRM_FORMAT_YUYV:
0659         cfg |= (GSC_OUT_YUV422_1P |
0660             GSC_OUT_YUV422_1P_ORDER_LSB_Y |
0661             GSC_OUT_CHROMA_ORDER_CBCR);
0662         break;
0663     case DRM_FORMAT_YVYU:
0664         cfg |= (GSC_OUT_YUV422_1P |
0665             GSC_OUT_YUV422_1P_ORDER_LSB_Y |
0666             GSC_OUT_CHROMA_ORDER_CRCB);
0667         break;
0668     case DRM_FORMAT_UYVY:
0669         cfg |= (GSC_OUT_YUV422_1P |
0670             GSC_OUT_YUV422_1P_OEDER_LSB_C |
0671             GSC_OUT_CHROMA_ORDER_CBCR);
0672         break;
0673     case DRM_FORMAT_VYUY:
0674         cfg |= (GSC_OUT_YUV422_1P |
0675             GSC_OUT_YUV422_1P_OEDER_LSB_C |
0676             GSC_OUT_CHROMA_ORDER_CRCB);
0677         break;
0678     case DRM_FORMAT_NV21:
0679         cfg |= (GSC_OUT_CHROMA_ORDER_CRCB | GSC_OUT_YUV420_2P);
0680         break;
0681     case DRM_FORMAT_NV61:
0682         cfg |= (GSC_OUT_CHROMA_ORDER_CRCB | GSC_OUT_YUV422_2P);
0683         break;
0684     case DRM_FORMAT_YUV422:
0685         cfg |= GSC_OUT_YUV422_3P;
0686         break;
0687     case DRM_FORMAT_YUV420:
0688         cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | GSC_OUT_YUV420_3P);
0689         break;
0690     case DRM_FORMAT_YVU420:
0691         cfg |= (GSC_OUT_CHROMA_ORDER_CRCB | GSC_OUT_YUV420_3P);
0692         break;
0693     case DRM_FORMAT_NV12:
0694         cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | GSC_OUT_YUV420_2P);
0695         break;
0696     case DRM_FORMAT_NV16:
0697         cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | GSC_OUT_YUV422_2P);
0698         break;
0699     }
0700 
0701     if (tiled)
0702         cfg |= (GSC_IN_TILE_C_16x8 | GSC_OUT_TILE_MODE);
0703 
0704     gsc_write(cfg, GSC_OUT_CON);
0705 }
0706 
0707 static int gsc_get_ratio_shift(struct gsc_context *ctx, u32 src, u32 dst,
0708                    u32 *ratio)
0709 {
0710     DRM_DEV_DEBUG_KMS(ctx->dev, "src[%d]dst[%d]\n", src, dst);
0711 
0712     if (src >= dst * 8) {
0713         DRM_DEV_ERROR(ctx->dev, "failed to make ratio and shift.\n");
0714         return -EINVAL;
0715     } else if (src >= dst * 4)
0716         *ratio = 4;
0717     else if (src >= dst * 2)
0718         *ratio = 2;
0719     else
0720         *ratio = 1;
0721 
0722     return 0;
0723 }
0724 
0725 static void gsc_get_prescaler_shfactor(u32 hratio, u32 vratio, u32 *shfactor)
0726 {
0727     if (hratio == 4 && vratio == 4)
0728         *shfactor = 4;
0729     else if ((hratio == 4 && vratio == 2) ||
0730          (hratio == 2 && vratio == 4))
0731         *shfactor = 3;
0732     else if ((hratio == 4 && vratio == 1) ||
0733          (hratio == 1 && vratio == 4) ||
0734          (hratio == 2 && vratio == 2))
0735         *shfactor = 2;
0736     else if (hratio == 1 && vratio == 1)
0737         *shfactor = 0;
0738     else
0739         *shfactor = 1;
0740 }
0741 
0742 static int gsc_set_prescaler(struct gsc_context *ctx, struct gsc_scaler *sc,
0743                  struct drm_exynos_ipp_task_rect *src,
0744                  struct drm_exynos_ipp_task_rect *dst)
0745 {
0746     u32 cfg;
0747     u32 src_w, src_h, dst_w, dst_h;
0748     int ret = 0;
0749 
0750     src_w = src->w;
0751     src_h = src->h;
0752 
0753     if (ctx->rotation) {
0754         dst_w = dst->h;
0755         dst_h = dst->w;
0756     } else {
0757         dst_w = dst->w;
0758         dst_h = dst->h;
0759     }
0760 
0761     ret = gsc_get_ratio_shift(ctx, src_w, dst_w, &sc->pre_hratio);
0762     if (ret) {
0763         DRM_DEV_ERROR(ctx->dev, "failed to get ratio horizontal.\n");
0764         return ret;
0765     }
0766 
0767     ret = gsc_get_ratio_shift(ctx, src_h, dst_h, &sc->pre_vratio);
0768     if (ret) {
0769         DRM_DEV_ERROR(ctx->dev, "failed to get ratio vertical.\n");
0770         return ret;
0771     }
0772 
0773     DRM_DEV_DEBUG_KMS(ctx->dev, "pre_hratio[%d]pre_vratio[%d]\n",
0774               sc->pre_hratio, sc->pre_vratio);
0775 
0776     sc->main_hratio = (src_w << 16) / dst_w;
0777     sc->main_vratio = (src_h << 16) / dst_h;
0778 
0779     DRM_DEV_DEBUG_KMS(ctx->dev, "main_hratio[%ld]main_vratio[%ld]\n",
0780               sc->main_hratio, sc->main_vratio);
0781 
0782     gsc_get_prescaler_shfactor(sc->pre_hratio, sc->pre_vratio,
0783         &sc->pre_shfactor);
0784 
0785     DRM_DEV_DEBUG_KMS(ctx->dev, "pre_shfactor[%d]\n", sc->pre_shfactor);
0786 
0787     cfg = (GSC_PRESC_SHFACTOR(sc->pre_shfactor) |
0788         GSC_PRESC_H_RATIO(sc->pre_hratio) |
0789         GSC_PRESC_V_RATIO(sc->pre_vratio));
0790     gsc_write(cfg, GSC_PRE_SCALE_RATIO);
0791 
0792     return ret;
0793 }
0794 
0795 static void gsc_set_h_coef(struct gsc_context *ctx, unsigned long main_hratio)
0796 {
0797     int i, j, k, sc_ratio;
0798 
0799     if (main_hratio <= GSC_SC_UP_MAX_RATIO)
0800         sc_ratio = 0;
0801     else if (main_hratio <= GSC_SC_DOWN_RATIO_7_8)
0802         sc_ratio = 1;
0803     else if (main_hratio <= GSC_SC_DOWN_RATIO_6_8)
0804         sc_ratio = 2;
0805     else if (main_hratio <= GSC_SC_DOWN_RATIO_5_8)
0806         sc_ratio = 3;
0807     else if (main_hratio <= GSC_SC_DOWN_RATIO_4_8)
0808         sc_ratio = 4;
0809     else if (main_hratio <= GSC_SC_DOWN_RATIO_3_8)
0810         sc_ratio = 5;
0811     else
0812         sc_ratio = 6;
0813 
0814     for (i = 0; i < GSC_COEF_PHASE; i++)
0815         for (j = 0; j < GSC_COEF_H_8T; j++)
0816             for (k = 0; k < GSC_COEF_DEPTH; k++)
0817                 gsc_write(h_coef_8t[sc_ratio][i][j],
0818                     GSC_HCOEF(i, j, k));
0819 }
0820 
0821 static void gsc_set_v_coef(struct gsc_context *ctx, unsigned long main_vratio)
0822 {
0823     int i, j, k, sc_ratio;
0824 
0825     if (main_vratio <= GSC_SC_UP_MAX_RATIO)
0826         sc_ratio = 0;
0827     else if (main_vratio <= GSC_SC_DOWN_RATIO_7_8)
0828         sc_ratio = 1;
0829     else if (main_vratio <= GSC_SC_DOWN_RATIO_6_8)
0830         sc_ratio = 2;
0831     else if (main_vratio <= GSC_SC_DOWN_RATIO_5_8)
0832         sc_ratio = 3;
0833     else if (main_vratio <= GSC_SC_DOWN_RATIO_4_8)
0834         sc_ratio = 4;
0835     else if (main_vratio <= GSC_SC_DOWN_RATIO_3_8)
0836         sc_ratio = 5;
0837     else
0838         sc_ratio = 6;
0839 
0840     for (i = 0; i < GSC_COEF_PHASE; i++)
0841         for (j = 0; j < GSC_COEF_V_4T; j++)
0842             for (k = 0; k < GSC_COEF_DEPTH; k++)
0843                 gsc_write(v_coef_4t[sc_ratio][i][j],
0844                     GSC_VCOEF(i, j, k));
0845 }
0846 
0847 static void gsc_set_scaler(struct gsc_context *ctx, struct gsc_scaler *sc)
0848 {
0849     u32 cfg;
0850 
0851     DRM_DEV_DEBUG_KMS(ctx->dev, "main_hratio[%ld]main_vratio[%ld]\n",
0852               sc->main_hratio, sc->main_vratio);
0853 
0854     gsc_set_h_coef(ctx, sc->main_hratio);
0855     cfg = GSC_MAIN_H_RATIO_VALUE(sc->main_hratio);
0856     gsc_write(cfg, GSC_MAIN_H_RATIO);
0857 
0858     gsc_set_v_coef(ctx, sc->main_vratio);
0859     cfg = GSC_MAIN_V_RATIO_VALUE(sc->main_vratio);
0860     gsc_write(cfg, GSC_MAIN_V_RATIO);
0861 }
0862 
0863 static void gsc_dst_set_size(struct gsc_context *ctx,
0864                  struct exynos_drm_ipp_buffer *buf)
0865 {
0866     struct gsc_scaler *sc = &ctx->sc;
0867     u32 cfg;
0868 
0869     /* pixel offset */
0870     cfg = (GSC_DSTIMG_OFFSET_X(buf->rect.x) |
0871         GSC_DSTIMG_OFFSET_Y(buf->rect.y));
0872     gsc_write(cfg, GSC_DSTIMG_OFFSET);
0873 
0874     /* scaled size */
0875     if (ctx->rotation)
0876         cfg = (GSC_SCALED_WIDTH(buf->rect.h) |
0877                GSC_SCALED_HEIGHT(buf->rect.w));
0878     else
0879         cfg = (GSC_SCALED_WIDTH(buf->rect.w) |
0880                GSC_SCALED_HEIGHT(buf->rect.h));
0881     gsc_write(cfg, GSC_SCALED_SIZE);
0882 
0883     /* original size */
0884     cfg = gsc_read(GSC_DSTIMG_SIZE);
0885     cfg &= ~(GSC_DSTIMG_HEIGHT_MASK | GSC_DSTIMG_WIDTH_MASK);
0886     cfg |= GSC_DSTIMG_WIDTH(buf->buf.pitch[0] / buf->format->cpp[0]) |
0887            GSC_DSTIMG_HEIGHT(buf->buf.height);
0888     gsc_write(cfg, GSC_DSTIMG_SIZE);
0889 
0890     cfg = gsc_read(GSC_OUT_CON);
0891     cfg &= ~GSC_OUT_RGB_TYPE_MASK;
0892 
0893     if (buf->rect.w >= GSC_WIDTH_ITU_709)
0894         if (sc->range)
0895             cfg |= GSC_OUT_RGB_HD_WIDE;
0896         else
0897             cfg |= GSC_OUT_RGB_HD_NARROW;
0898     else
0899         if (sc->range)
0900             cfg |= GSC_OUT_RGB_SD_WIDE;
0901         else
0902             cfg |= GSC_OUT_RGB_SD_NARROW;
0903 
0904     gsc_write(cfg, GSC_OUT_CON);
0905 }
0906 
0907 static int gsc_dst_get_buf_seq(struct gsc_context *ctx)
0908 {
0909     u32 cfg, i, buf_num = GSC_REG_SZ;
0910     u32 mask = 0x00000001;
0911 
0912     cfg = gsc_read(GSC_OUT_BASE_ADDR_Y_MASK);
0913 
0914     for (i = 0; i < GSC_REG_SZ; i++)
0915         if (cfg & (mask << i))
0916             buf_num--;
0917 
0918     DRM_DEV_DEBUG_KMS(ctx->dev, "buf_num[%d]\n", buf_num);
0919 
0920     return buf_num;
0921 }
0922 
0923 static void gsc_dst_set_buf_seq(struct gsc_context *ctx, u32 buf_id,
0924                 bool enqueue)
0925 {
0926     bool masked = !enqueue;
0927     u32 cfg;
0928     u32 mask = 0x00000001 << buf_id;
0929 
0930     /* mask register set */
0931     cfg = gsc_read(GSC_OUT_BASE_ADDR_Y_MASK);
0932 
0933     /* sequence id */
0934     cfg &= ~mask;
0935     cfg |= masked << buf_id;
0936     gsc_write(cfg, GSC_OUT_BASE_ADDR_Y_MASK);
0937     gsc_write(cfg, GSC_OUT_BASE_ADDR_CB_MASK);
0938     gsc_write(cfg, GSC_OUT_BASE_ADDR_CR_MASK);
0939 
0940     /* interrupt enable */
0941     if (enqueue && gsc_dst_get_buf_seq(ctx) >= GSC_BUF_START)
0942         gsc_handle_irq(ctx, true, false, true);
0943 
0944     /* interrupt disable */
0945     if (!enqueue && gsc_dst_get_buf_seq(ctx) <= GSC_BUF_STOP)
0946         gsc_handle_irq(ctx, false, false, true);
0947 }
0948 
0949 static void gsc_dst_set_addr(struct gsc_context *ctx,
0950                  u32 buf_id, struct exynos_drm_ipp_buffer *buf)
0951 {
0952     /* address register set */
0953     gsc_write(buf->dma_addr[0], GSC_OUT_BASE_ADDR_Y(buf_id));
0954     gsc_write(buf->dma_addr[1], GSC_OUT_BASE_ADDR_CB(buf_id));
0955     gsc_write(buf->dma_addr[2], GSC_OUT_BASE_ADDR_CR(buf_id));
0956 
0957     gsc_dst_set_buf_seq(ctx, buf_id, true);
0958 }
0959 
0960 static int gsc_get_src_buf_index(struct gsc_context *ctx)
0961 {
0962     u32 cfg, curr_index, i;
0963     u32 buf_id = GSC_MAX_SRC;
0964 
0965     DRM_DEV_DEBUG_KMS(ctx->dev, "gsc id[%d]\n", ctx->id);
0966 
0967     cfg = gsc_read(GSC_IN_BASE_ADDR_Y_MASK);
0968     curr_index = GSC_IN_CURR_GET_INDEX(cfg);
0969 
0970     for (i = curr_index; i < GSC_MAX_SRC; i++) {
0971         if (!((cfg >> i) & 0x1)) {
0972             buf_id = i;
0973             break;
0974         }
0975     }
0976 
0977     DRM_DEV_DEBUG_KMS(ctx->dev, "cfg[0x%x]curr_index[%d]buf_id[%d]\n", cfg,
0978               curr_index, buf_id);
0979 
0980     if (buf_id == GSC_MAX_SRC) {
0981         DRM_DEV_ERROR(ctx->dev, "failed to get in buffer index.\n");
0982         return -EINVAL;
0983     }
0984 
0985     gsc_src_set_buf_seq(ctx, buf_id, false);
0986 
0987     return buf_id;
0988 }
0989 
0990 static int gsc_get_dst_buf_index(struct gsc_context *ctx)
0991 {
0992     u32 cfg, curr_index, i;
0993     u32 buf_id = GSC_MAX_DST;
0994 
0995     DRM_DEV_DEBUG_KMS(ctx->dev, "gsc id[%d]\n", ctx->id);
0996 
0997     cfg = gsc_read(GSC_OUT_BASE_ADDR_Y_MASK);
0998     curr_index = GSC_OUT_CURR_GET_INDEX(cfg);
0999 
1000     for (i = curr_index; i < GSC_MAX_DST; i++) {
1001         if (!((cfg >> i) & 0x1)) {
1002             buf_id = i;
1003             break;
1004         }
1005     }
1006 
1007     if (buf_id == GSC_MAX_DST) {
1008         DRM_DEV_ERROR(ctx->dev, "failed to get out buffer index.\n");
1009         return -EINVAL;
1010     }
1011 
1012     gsc_dst_set_buf_seq(ctx, buf_id, false);
1013 
1014     DRM_DEV_DEBUG_KMS(ctx->dev, "cfg[0x%x]curr_index[%d]buf_id[%d]\n", cfg,
1015               curr_index, buf_id);
1016 
1017     return buf_id;
1018 }
1019 
1020 static irqreturn_t gsc_irq_handler(int irq, void *dev_id)
1021 {
1022     struct gsc_context *ctx = dev_id;
1023     u32 status;
1024     int err = 0;
1025 
1026     DRM_DEV_DEBUG_KMS(ctx->dev, "gsc id[%d]\n", ctx->id);
1027 
1028     status = gsc_read(GSC_IRQ);
1029     if (status & GSC_IRQ_STATUS_OR_IRQ) {
1030         dev_err(ctx->dev, "occurred overflow at %d, status 0x%x.\n",
1031             ctx->id, status);
1032         err = -EINVAL;
1033     }
1034 
1035     if (status & GSC_IRQ_STATUS_OR_FRM_DONE) {
1036         int src_buf_id, dst_buf_id;
1037 
1038         dev_dbg(ctx->dev, "occurred frame done at %d, status 0x%x.\n",
1039             ctx->id, status);
1040 
1041         src_buf_id = gsc_get_src_buf_index(ctx);
1042         dst_buf_id = gsc_get_dst_buf_index(ctx);
1043 
1044         DRM_DEV_DEBUG_KMS(ctx->dev, "buf_id_src[%d]buf_id_dst[%d]\n",
1045                   src_buf_id, dst_buf_id);
1046 
1047         if (src_buf_id < 0 || dst_buf_id < 0)
1048             err = -EINVAL;
1049     }
1050 
1051     if (ctx->task) {
1052         struct exynos_drm_ipp_task *task = ctx->task;
1053 
1054         ctx->task = NULL;
1055         pm_runtime_mark_last_busy(ctx->dev);
1056         pm_runtime_put_autosuspend(ctx->dev);
1057         exynos_drm_ipp_task_done(task, err);
1058     }
1059 
1060     return IRQ_HANDLED;
1061 }
1062 
1063 static int gsc_reset(struct gsc_context *ctx)
1064 {
1065     struct gsc_scaler *sc = &ctx->sc;
1066     int ret;
1067 
1068     /* reset h/w block */
1069     ret = gsc_sw_reset(ctx);
1070     if (ret < 0) {
1071         dev_err(ctx->dev, "failed to reset hardware.\n");
1072         return ret;
1073     }
1074 
1075     /* scaler setting */
1076     memset(&ctx->sc, 0x0, sizeof(ctx->sc));
1077     sc->range = true;
1078 
1079     return 0;
1080 }
1081 
1082 static void gsc_start(struct gsc_context *ctx)
1083 {
1084     u32 cfg;
1085 
1086     gsc_handle_irq(ctx, true, false, true);
1087 
1088     /* enable one shot */
1089     cfg = gsc_read(GSC_ENABLE);
1090     cfg &= ~(GSC_ENABLE_ON_CLEAR_MASK |
1091         GSC_ENABLE_CLK_GATE_MODE_MASK);
1092     cfg |= GSC_ENABLE_ON_CLEAR_ONESHOT;
1093     gsc_write(cfg, GSC_ENABLE);
1094 
1095     /* src dma memory */
1096     cfg = gsc_read(GSC_IN_CON);
1097     cfg &= ~(GSC_IN_PATH_MASK | GSC_IN_LOCAL_SEL_MASK);
1098     cfg |= GSC_IN_PATH_MEMORY;
1099     gsc_write(cfg, GSC_IN_CON);
1100 
1101     /* dst dma memory */
1102     cfg = gsc_read(GSC_OUT_CON);
1103     cfg |= GSC_OUT_PATH_MEMORY;
1104     gsc_write(cfg, GSC_OUT_CON);
1105 
1106     gsc_set_scaler(ctx, &ctx->sc);
1107 
1108     cfg = gsc_read(GSC_ENABLE);
1109     cfg |= GSC_ENABLE_ON;
1110     gsc_write(cfg, GSC_ENABLE);
1111 }
1112 
1113 static int gsc_commit(struct exynos_drm_ipp *ipp,
1114               struct exynos_drm_ipp_task *task)
1115 {
1116     struct gsc_context *ctx = container_of(ipp, struct gsc_context, ipp);
1117     int ret;
1118 
1119     ret = pm_runtime_resume_and_get(ctx->dev);
1120     if (ret < 0) {
1121         dev_err(ctx->dev, "failed to enable GScaler device.\n");
1122         return ret;
1123     }
1124 
1125     ctx->task = task;
1126 
1127     ret = gsc_reset(ctx);
1128     if (ret) {
1129         pm_runtime_put_autosuspend(ctx->dev);
1130         ctx->task = NULL;
1131         return ret;
1132     }
1133 
1134     gsc_src_set_fmt(ctx, task->src.buf.fourcc, task->src.buf.modifier);
1135     gsc_src_set_transf(ctx, task->transform.rotation);
1136     gsc_src_set_size(ctx, &task->src);
1137     gsc_src_set_addr(ctx, 0, &task->src);
1138     gsc_dst_set_fmt(ctx, task->dst.buf.fourcc, task->dst.buf.modifier);
1139     gsc_dst_set_size(ctx, &task->dst);
1140     gsc_dst_set_addr(ctx, 0, &task->dst);
1141     gsc_set_prescaler(ctx, &ctx->sc, &task->src.rect, &task->dst.rect);
1142     gsc_start(ctx);
1143 
1144     return 0;
1145 }
1146 
1147 static void gsc_abort(struct exynos_drm_ipp *ipp,
1148               struct exynos_drm_ipp_task *task)
1149 {
1150     struct gsc_context *ctx =
1151             container_of(ipp, struct gsc_context, ipp);
1152 
1153     gsc_reset(ctx);
1154     if (ctx->task) {
1155         struct exynos_drm_ipp_task *task = ctx->task;
1156 
1157         ctx->task = NULL;
1158         pm_runtime_mark_last_busy(ctx->dev);
1159         pm_runtime_put_autosuspend(ctx->dev);
1160         exynos_drm_ipp_task_done(task, -EIO);
1161     }
1162 }
1163 
1164 static struct exynos_drm_ipp_funcs ipp_funcs = {
1165     .commit = gsc_commit,
1166     .abort = gsc_abort,
1167 };
1168 
1169 static int gsc_bind(struct device *dev, struct device *master, void *data)
1170 {
1171     struct gsc_context *ctx = dev_get_drvdata(dev);
1172     struct drm_device *drm_dev = data;
1173     struct exynos_drm_ipp *ipp = &ctx->ipp;
1174 
1175     ctx->drm_dev = drm_dev;
1176     ctx->drm_dev = drm_dev;
1177     exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv);
1178 
1179     exynos_drm_ipp_register(dev, ipp, &ipp_funcs,
1180             DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE |
1181             DRM_EXYNOS_IPP_CAP_SCALE | DRM_EXYNOS_IPP_CAP_CONVERT,
1182             ctx->formats, ctx->num_formats, "gsc");
1183 
1184     dev_info(dev, "The exynos gscaler has been probed successfully\n");
1185 
1186     return 0;
1187 }
1188 
1189 static void gsc_unbind(struct device *dev, struct device *master,
1190             void *data)
1191 {
1192     struct gsc_context *ctx = dev_get_drvdata(dev);
1193     struct drm_device *drm_dev = data;
1194     struct exynos_drm_ipp *ipp = &ctx->ipp;
1195 
1196     exynos_drm_ipp_unregister(dev, ipp);
1197     exynos_drm_unregister_dma(drm_dev, dev, &ctx->dma_priv);
1198 }
1199 
1200 static const struct component_ops gsc_component_ops = {
1201     .bind   = gsc_bind,
1202     .unbind = gsc_unbind,
1203 };
1204 
1205 static const unsigned int gsc_formats[] = {
1206     DRM_FORMAT_ARGB8888,
1207     DRM_FORMAT_XRGB8888, DRM_FORMAT_RGB565, DRM_FORMAT_BGRX8888,
1208     DRM_FORMAT_NV12, DRM_FORMAT_NV16, DRM_FORMAT_NV21, DRM_FORMAT_NV61,
1209     DRM_FORMAT_UYVY, DRM_FORMAT_VYUY, DRM_FORMAT_YUYV, DRM_FORMAT_YVYU,
1210     DRM_FORMAT_YUV420, DRM_FORMAT_YVU420, DRM_FORMAT_YUV422,
1211 };
1212 
1213 static const unsigned int gsc_tiled_formats[] = {
1214     DRM_FORMAT_NV12, DRM_FORMAT_NV21,
1215 };
1216 
1217 static int gsc_probe(struct platform_device *pdev)
1218 {
1219     struct device *dev = &pdev->dev;
1220     struct gsc_driverdata *driver_data;
1221     struct exynos_drm_ipp_formats *formats;
1222     struct gsc_context *ctx;
1223     int num_formats, ret, i, j;
1224 
1225     ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
1226     if (!ctx)
1227         return -ENOMEM;
1228 
1229     driver_data = (struct gsc_driverdata *)of_device_get_match_data(dev);
1230     ctx->dev = dev;
1231     ctx->num_clocks = driver_data->num_clocks;
1232     ctx->clk_names = driver_data->clk_names;
1233 
1234     /* construct formats/limits array */
1235     num_formats = ARRAY_SIZE(gsc_formats) + ARRAY_SIZE(gsc_tiled_formats);
1236     formats = devm_kcalloc(dev, num_formats, sizeof(*formats), GFP_KERNEL);
1237     if (!formats)
1238         return -ENOMEM;
1239 
1240     /* linear formats */
1241     for (i = 0; i < ARRAY_SIZE(gsc_formats); i++) {
1242         formats[i].fourcc = gsc_formats[i];
1243         formats[i].type = DRM_EXYNOS_IPP_FORMAT_SOURCE |
1244                   DRM_EXYNOS_IPP_FORMAT_DESTINATION;
1245         formats[i].limits = driver_data->limits;
1246         formats[i].num_limits = driver_data->num_limits;
1247     }
1248 
1249     /* tiled formats */
1250     for (j = i, i = 0; i < ARRAY_SIZE(gsc_tiled_formats); j++, i++) {
1251         formats[j].fourcc = gsc_tiled_formats[i];
1252         formats[j].modifier = DRM_FORMAT_MOD_SAMSUNG_16_16_TILE;
1253         formats[j].type = DRM_EXYNOS_IPP_FORMAT_SOURCE |
1254                   DRM_EXYNOS_IPP_FORMAT_DESTINATION;
1255         formats[j].limits = driver_data->limits;
1256         formats[j].num_limits = driver_data->num_limits;
1257     }
1258 
1259     ctx->formats = formats;
1260     ctx->num_formats = num_formats;
1261 
1262     /* clock control */
1263     for (i = 0; i < ctx->num_clocks; i++) {
1264         ctx->clocks[i] = devm_clk_get(dev, ctx->clk_names[i]);
1265         if (IS_ERR(ctx->clocks[i])) {
1266             dev_err(dev, "failed to get clock: %s\n",
1267                 ctx->clk_names[i]);
1268             return PTR_ERR(ctx->clocks[i]);
1269         }
1270     }
1271 
1272     ctx->regs = devm_platform_ioremap_resource(pdev, 0);
1273     if (IS_ERR(ctx->regs))
1274         return PTR_ERR(ctx->regs);
1275 
1276     /* resource irq */
1277     ctx->irq = platform_get_irq(pdev, 0);
1278     if (ctx->irq < 0)
1279         return ctx->irq;
1280 
1281     ret = devm_request_irq(dev, ctx->irq, gsc_irq_handler, 0,
1282                    dev_name(dev), ctx);
1283     if (ret < 0) {
1284         dev_err(dev, "failed to request irq.\n");
1285         return ret;
1286     }
1287 
1288     /* context initailization */
1289     ctx->id = pdev->id;
1290 
1291     platform_set_drvdata(pdev, ctx);
1292 
1293     pm_runtime_use_autosuspend(dev);
1294     pm_runtime_set_autosuspend_delay(dev, GSC_AUTOSUSPEND_DELAY);
1295     pm_runtime_enable(dev);
1296 
1297     ret = component_add(dev, &gsc_component_ops);
1298     if (ret)
1299         goto err_pm_dis;
1300 
1301     dev_info(dev, "drm gsc registered successfully.\n");
1302 
1303     return 0;
1304 
1305 err_pm_dis:
1306     pm_runtime_dont_use_autosuspend(dev);
1307     pm_runtime_disable(dev);
1308     return ret;
1309 }
1310 
1311 static int gsc_remove(struct platform_device *pdev)
1312 {
1313     struct device *dev = &pdev->dev;
1314 
1315     component_del(dev, &gsc_component_ops);
1316     pm_runtime_dont_use_autosuspend(dev);
1317     pm_runtime_disable(dev);
1318 
1319     return 0;
1320 }
1321 
1322 static int __maybe_unused gsc_runtime_suspend(struct device *dev)
1323 {
1324     struct gsc_context *ctx = get_gsc_context(dev);
1325     int i;
1326 
1327     DRM_DEV_DEBUG_KMS(dev, "id[%d]\n", ctx->id);
1328 
1329     for (i = ctx->num_clocks - 1; i >= 0; i--)
1330         clk_disable_unprepare(ctx->clocks[i]);
1331 
1332     return 0;
1333 }
1334 
1335 static int __maybe_unused gsc_runtime_resume(struct device *dev)
1336 {
1337     struct gsc_context *ctx = get_gsc_context(dev);
1338     int i, ret;
1339 
1340     DRM_DEV_DEBUG_KMS(dev, "id[%d]\n", ctx->id);
1341 
1342     for (i = 0; i < ctx->num_clocks; i++) {
1343         ret = clk_prepare_enable(ctx->clocks[i]);
1344         if (ret) {
1345             while (--i > 0)
1346                 clk_disable_unprepare(ctx->clocks[i]);
1347             return ret;
1348         }
1349     }
1350     return 0;
1351 }
1352 
1353 static const struct dev_pm_ops gsc_pm_ops = {
1354     SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1355                 pm_runtime_force_resume)
1356     SET_RUNTIME_PM_OPS(gsc_runtime_suspend, gsc_runtime_resume, NULL)
1357 };
1358 
1359 static const struct drm_exynos_ipp_limit gsc_5250_limits[] = {
1360     { IPP_SIZE_LIMIT(BUFFER, .h = { 32, 4800, 8 }, .v = { 16, 3344, 8 }) },
1361     { IPP_SIZE_LIMIT(AREA, .h = { 16, 4800, 2 }, .v = { 8, 3344, 2 }) },
1362     { IPP_SIZE_LIMIT(ROTATED, .h = { 32, 2048 }, .v = { 16, 2048 }) },
1363     { IPP_SCALE_LIMIT(.h = { (1 << 16) / 16, (1 << 16) * 8 },
1364               .v = { (1 << 16) / 16, (1 << 16) * 8 }) },
1365 };
1366 
1367 static const struct drm_exynos_ipp_limit gsc_5420_limits[] = {
1368     { IPP_SIZE_LIMIT(BUFFER, .h = { 32, 4800, 8 }, .v = { 16, 3344, 8 }) },
1369     { IPP_SIZE_LIMIT(AREA, .h = { 16, 4800, 2 }, .v = { 8, 3344, 2 }) },
1370     { IPP_SIZE_LIMIT(ROTATED, .h = { 16, 2016 }, .v = { 8, 2016 }) },
1371     { IPP_SCALE_LIMIT(.h = { (1 << 16) / 16, (1 << 16) * 8 },
1372               .v = { (1 << 16) / 16, (1 << 16) * 8 }) },
1373 };
1374 
1375 static const struct drm_exynos_ipp_limit gsc_5433_limits[] = {
1376     { IPP_SIZE_LIMIT(BUFFER, .h = { 32, 8191, 16 }, .v = { 16, 8191, 2 }) },
1377     { IPP_SIZE_LIMIT(AREA, .h = { 16, 4800, 1 }, .v = { 8, 3344, 1 }) },
1378     { IPP_SIZE_LIMIT(ROTATED, .h = { 32, 2047 }, .v = { 8, 8191 }) },
1379     { IPP_SCALE_LIMIT(.h = { (1 << 16) / 16, (1 << 16) * 8 },
1380               .v = { (1 << 16) / 16, (1 << 16) * 8 }) },
1381 };
1382 
1383 static struct gsc_driverdata gsc_exynos5250_drvdata = {
1384     .clk_names = {"gscl"},
1385     .num_clocks = 1,
1386     .limits = gsc_5250_limits,
1387     .num_limits = ARRAY_SIZE(gsc_5250_limits),
1388 };
1389 
1390 static struct gsc_driverdata gsc_exynos5420_drvdata = {
1391     .clk_names = {"gscl"},
1392     .num_clocks = 1,
1393     .limits = gsc_5420_limits,
1394     .num_limits = ARRAY_SIZE(gsc_5420_limits),
1395 };
1396 
1397 static struct gsc_driverdata gsc_exynos5433_drvdata = {
1398     .clk_names = {"pclk", "aclk", "aclk_xiu", "aclk_gsclbend"},
1399     .num_clocks = 4,
1400     .limits = gsc_5433_limits,
1401     .num_limits = ARRAY_SIZE(gsc_5433_limits),
1402 };
1403 
1404 static const struct of_device_id exynos_drm_gsc_of_match[] = {
1405     {
1406         .compatible = "samsung,exynos5-gsc",
1407         .data = &gsc_exynos5250_drvdata,
1408     }, {
1409         .compatible = "samsung,exynos5250-gsc",
1410         .data = &gsc_exynos5250_drvdata,
1411     }, {
1412         .compatible = "samsung,exynos5420-gsc",
1413         .data = &gsc_exynos5420_drvdata,
1414     }, {
1415         .compatible = "samsung,exynos5433-gsc",
1416         .data = &gsc_exynos5433_drvdata,
1417     }, {
1418     },
1419 };
1420 MODULE_DEVICE_TABLE(of, exynos_drm_gsc_of_match);
1421 
1422 struct platform_driver gsc_driver = {
1423     .probe      = gsc_probe,
1424     .remove     = gsc_remove,
1425     .driver     = {
1426         .name   = "exynos-drm-gsc",
1427         .owner  = THIS_MODULE,
1428         .pm = &gsc_pm_ops,
1429         .of_match_table = of_match_ptr(exynos_drm_gsc_of_match),
1430     },
1431 };