0001
0002
0003
0004
0005
0006
0007
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
0029
0030
0031
0032
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
0069
0070
0071
0072
0073
0074
0075
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
0088
0089
0090
0091
0092
0093
0094
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
0117
0118
0119
0120
0121
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
0131 static const int h_coef_8t[GSC_COEF_RATIO][GSC_COEF_ATTR][GSC_COEF_H_8T] = {
0132 {
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 }, {
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 }, {
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 }, {
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 }, {
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 }, {
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 }, {
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
0255 static const int v_coef_4t[GSC_COEF_RATIO][GSC_COEF_ATTR][GSC_COEF_V_4T] = {
0256 {
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 }, {
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 }, {
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 }, {
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 }, {
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 }, {
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 }, {
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
0384 cfg = (GSC_SW_RESET_SRESET);
0385 gsc_write(cfg, GSC_SW_RESET);
0386
0387
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
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
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
0575 cfg = (GSC_CROPPED_WIDTH(buf->rect.w) |
0576 GSC_CROPPED_HEIGHT(buf->rect.h));
0577 gsc_write(cfg, GSC_CROPPED_SIZE);
0578
0579
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
0614 cfg = gsc_read(GSC_IN_BASE_ADDR_Y_MASK);
0615
0616
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
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
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
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
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
0931 cfg = gsc_read(GSC_OUT_BASE_ADDR_Y_MASK);
0932
0933
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
0941 if (enqueue && gsc_dst_get_buf_seq(ctx) >= GSC_BUF_START)
0942 gsc_handle_irq(ctx, true, false, true);
0943
0944
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
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
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
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
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
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
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
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
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
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
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
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
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 };