Lines Matching +full:exynos5 +full:- +full:gsc
1 // SPDX-License-Identifier: GPL-2.0-or-later
26 #include "regs-gsc.h"
29 * GSC stands for General SCaler and
33 * GSC supports image rotation and image effect functions.
65 #define gsc_read(offset) readl(ctx->regs + (offset))
66 #define gsc_write(cfg, offset) writel(cfg, ctx->regs + (offset))
88 * A structure of gsc context.
91 * @gsc_clk: gsc gate clock.
93 * @id: gsc id.
117 * struct gsc_driverdata - per device type driver data for init time.
131 /* 8-tap Filter Coefficient */
135 { -1, 2, -6, 127, 7, -2, 1, 0 },
136 { -1, 4, -12, 125, 16, -5, 1, 0 },
137 { -1, 5, -15, 120, 25, -8, 2, 0 },
138 { -1, 6, -18, 114, 35, -10, 3, -1 },
139 { -1, 6, -20, 107, 46, -13, 4, -1 },
140 { -2, 7, -21, 99, 57, -16, 5, -1 },
141 { -1, 6, -20, 89, 68, -18, 5, -1 },
142 { -1, 6, -20, 79, 79, -20, 6, -1 },
143 { -1, 5, -18, 68, 89, -20, 6, -1 },
144 { -1, 5, -16, 57, 99, -21, 7, -2 },
145 { -1, 4, -13, 46, 107, -20, 6, -1 },
146 { -1, 3, -10, 35, 114, -18, 6, -1 },
147 { 0, 2, -8, 25, 120, -15, 5, -1 },
148 { 0, 1, -5, 16, 125, -12, 4, -1 },
149 { 0, 1, -2, 7, 127, -6, 2, -1 }
151 { 3, -8, 14, 111, 13, -8, 3, 0 },
152 { 2, -6, 7, 112, 21, -10, 3, -1 },
153 { 2, -4, 1, 110, 28, -12, 4, -1 },
154 { 1, -2, -3, 106, 36, -13, 4, -1 },
155 { 1, -1, -7, 103, 44, -15, 4, -1 },
156 { 1, 1, -11, 97, 53, -16, 4, -1 },
157 { 0, 2, -13, 91, 61, -16, 4, -1 },
158 { 0, 3, -15, 85, 69, -17, 4, -1 },
159 { 0, 3, -16, 77, 77, -16, 3, 0 },
160 { -1, 4, -17, 69, 85, -15, 3, 0 },
161 { -1, 4, -16, 61, 91, -13, 2, 0 },
162 { -1, 4, -16, 53, 97, -11, 1, 1 },
163 { -1, 4, -15, 44, 103, -7, -1, 1 },
164 { -1, 4, -13, 36, 106, -3, -2, 1 },
165 { -1, 4, -12, 28, 110, 1, -4, 2 },
166 { -1, 3, -10, 21, 112, 7, -6, 2 }
168 { 2, -11, 25, 96, 25, -11, 2, 0 },
169 { 2, -10, 19, 96, 31, -12, 2, 0 },
170 { 2, -9, 14, 94, 37, -12, 2, 0 },
171 { 2, -8, 10, 92, 43, -12, 1, 0 },
172 { 2, -7, 5, 90, 49, -12, 1, 0 },
173 { 2, -5, 1, 86, 55, -12, 0, 1 },
174 { 2, -4, -2, 82, 61, -11, -1, 1 },
175 { 1, -3, -5, 77, 67, -9, -1, 1 },
176 { 1, -2, -7, 72, 72, -7, -2, 1 },
177 { 1, -1, -9, 67, 77, -5, -3, 1 },
178 { 1, -1, -11, 61, 82, -2, -4, 2 },
179 { 1, 0, -12, 55, 86, 1, -5, 2 },
180 { 0, 1, -12, 49, 90, 5, -7, 2 },
181 { 0, 1, -12, 43, 92, 10, -8, 2 },
182 { 0, 2, -12, 37, 94, 14, -9, 2 },
183 { 0, 2, -12, 31, 96, 19, -10, 2 }
185 { -1, -8, 33, 80, 33, -8, -1, 0 },
186 { -1, -8, 28, 80, 37, -7, -2, 1 },
187 { 0, -8, 24, 79, 41, -7, -2, 1 },
188 { 0, -8, 20, 78, 46, -6, -3, 1 },
189 { 0, -8, 16, 76, 50, -4, -3, 1 },
190 { 0, -7, 13, 74, 54, -3, -4, 1 },
191 { 1, -7, 10, 71, 58, -1, -5, 1 },
192 { 1, -6, 6, 68, 62, 1, -5, 1 },
193 { 1, -6, 4, 65, 65, 4, -6, 1 },
194 { 1, -5, 1, 62, 68, 6, -6, 1 },
195 { 1, -5, -1, 58, 71, 10, -7, 1 },
196 { 1, -4, -3, 54, 74, 13, -7, 0 },
197 { 1, -3, -4, 50, 76, 16, -8, 0 },
198 { 1, -3, -6, 46, 78, 20, -8, 0 },
199 { 1, -2, -7, 41, 79, 24, -8, 0 },
200 { 1, -2, -7, 37, 80, 28, -8, -1 }
202 { -3, 0, 35, 64, 35, 0, -3, 0 },
203 { -3, -1, 32, 64, 38, 1, -3, 0 },
204 { -2, -2, 29, 63, 41, 2, -3, 0 },
205 { -2, -3, 27, 63, 43, 4, -4, 0 },
206 { -2, -3, 24, 61, 46, 6, -4, 0 },
207 { -2, -3, 21, 60, 49, 7, -4, 0 },
208 { -1, -4, 19, 59, 51, 9, -4, -1 },
209 { -1, -4, 16, 57, 53, 12, -4, -1 },
210 { -1, -4, 14, 55, 55, 14, -4, -1 },
211 { -1, -4, 12, 53, 57, 16, -4, -1 },
212 { -1, -4, 9, 51, 59, 19, -4, -1 },
213 { 0, -4, 7, 49, 60, 21, -3, -2 },
214 { 0, -4, 6, 46, 61, 24, -3, -2 },
215 { 0, -4, 4, 43, 63, 27, -3, -2 },
216 { 0, -3, 2, 41, 63, 29, -2, -2 },
217 { 0, -3, 1, 38, 64, 32, -1, -3 }
219 { -1, 8, 33, 48, 33, 8, -1, 0 },
220 { -1, 7, 31, 49, 35, 9, -1, -1 },
221 { -1, 6, 30, 49, 36, 10, -1, -1 },
222 { -1, 5, 28, 48, 38, 12, -1, -1 },
223 { -1, 4, 26, 48, 39, 13, 0, -1 },
224 { -1, 3, 24, 47, 41, 15, 0, -1 },
225 { -1, 2, 23, 47, 42, 16, 0, -1 },
226 { -1, 2, 21, 45, 43, 18, 1, -1 },
227 { -1, 1, 19, 45, 45, 19, 1, -1 },
228 { -1, 1, 18, 43, 45, 21, 2, -1 },
229 { -1, 0, 16, 42, 47, 23, 2, -1 },
230 { -1, 0, 15, 41, 47, 24, 3, -1 },
231 { -1, 0, 13, 39, 48, 26, 4, -1 },
232 { -1, -1, 12, 38, 48, 28, 5, -1 },
233 { -1, -1, 10, 36, 49, 30, 6, -1 },
234 { -1, -1, 9, 35, 49, 31, 7, -1 }
255 /* 4-tap Filter Coefficient */
259 { -4, 127, 5, 0 },
260 { -6, 124, 11, -1 },
261 { -8, 118, 19, -1 },
262 { -8, 111, 27, -2 },
263 { -8, 102, 37, -3 },
264 { -8, 92, 48, -4 },
265 { -7, 81, 59, -5 },
266 { -6, 70, 70, -6 },
267 { -5, 59, 81, -7 },
268 { -4, 48, 92, -8 },
269 { -3, 37, 102, -8 },
270 { -2, 27, 111, -8 },
271 { -1, 19, 118, -8 },
272 { -1, 11, 124, -6 },
273 { 0, 5, 127, -4 }
276 { 4, 111, 14, -1 },
277 { 1, 109, 20, -2 },
278 { -2, 105, 27, -2 },
279 { -3, 100, 34, -3 },
280 { -5, 93, 43, -3 },
281 { -5, 86, 51, -4 },
282 { -5, 77, 60, -4 },
283 { -5, 69, 69, -5 },
284 { -4, 60, 77, -5 },
285 { -4, 51, 86, -5 },
286 { -3, 43, 93, -5 },
287 { -3, 34, 100, -3 },
288 { -2, 27, 105, -2 },
289 { -2, 20, 109, 1 },
290 { -1, 14, 111, 4 }
293 { 12, 97, 21, -2 },
294 { 8, 96, 26, -2 },
295 { 5, 93, 32, -2 },
296 { 2, 89, 39, -2 },
297 { 0, 84, 46, -2 },
298 { -1, 79, 53, -3 },
299 { -2, 73, 59, -2 },
300 { -2, 66, 66, -2 },
301 { -2, 59, 73, -2 },
302 { -3, 53, 79, -1 },
303 { -2, 46, 84, 0 },
304 { -2, 39, 89, 2 },
305 { -2, 32, 93, 5 },
306 { -2, 26, 96, 8 },
307 { -2, 21, 97, 12 }
310 { 18, 85, 26, -1 },
311 { 14, 84, 31, -1 },
312 { 11, 82, 36, -1 },
313 { 8, 79, 42, -1 },
314 { 6, 76, 47, -1 },
320 { -1, 47, 76, 6 },
321 { -1, 42, 79, 8 },
322 { -1, 36, 82, 11 },
323 { -1, 31, 84, 14 },
324 { -1, 26, 85, 18 }
389 while (count--) { in gsc_sw_reset()
397 DRM_DEV_ERROR(ctx->dev, "failed to reset gsc h/w.\n"); in gsc_sw_reset()
398 return -EBUSY; in gsc_sw_reset()
424 DRM_DEV_DEBUG_KMS(ctx->dev, "enable[%d]overflow[%d]level[%d]\n", in gsc_handle_irq()
453 DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt); in gsc_src_set_fmt()
561 ctx->rotation = (cfg & GSC_IN_ROT_90) ? 1 : 0; in gsc_src_set_transf()
567 struct gsc_scaler *sc = &ctx->sc; in gsc_src_set_size()
571 cfg = (GSC_SRCIMG_OFFSET_X(buf->rect.x) | in gsc_src_set_size()
572 GSC_SRCIMG_OFFSET_Y(buf->rect.y)); in gsc_src_set_size()
576 cfg = (GSC_CROPPED_WIDTH(buf->rect.w) | in gsc_src_set_size()
577 GSC_CROPPED_HEIGHT(buf->rect.h)); in gsc_src_set_size()
585 cfg |= (GSC_SRCIMG_WIDTH(buf->buf.pitch[0] / buf->format->cpp[0]) | in gsc_src_set_size()
586 GSC_SRCIMG_HEIGHT(buf->buf.height)); in gsc_src_set_size()
593 if (buf->rect.w >= GSC_WIDTH_ITU_709) in gsc_src_set_size()
594 if (sc->range) in gsc_src_set_size()
599 if (sc->range) in gsc_src_set_size()
629 gsc_write(buf->dma_addr[0], GSC_IN_BASE_ADDR_Y(buf_id)); in gsc_src_set_addr()
630 gsc_write(buf->dma_addr[1], GSC_IN_BASE_ADDR_CB(buf_id)); in gsc_src_set_addr()
631 gsc_write(buf->dma_addr[2], GSC_IN_BASE_ADDR_CR(buf_id)); in gsc_src_set_addr()
640 DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt); in gsc_dst_set_fmt()
711 DRM_DEV_DEBUG_KMS(ctx->dev, "src[%d]dst[%d]\n", src, dst); in gsc_get_ratio_shift()
714 DRM_DEV_ERROR(ctx->dev, "failed to make ratio and shift.\n"); in gsc_get_ratio_shift()
715 return -EINVAL; in gsc_get_ratio_shift()
751 src_w = src->w; in gsc_set_prescaler()
752 src_h = src->h; in gsc_set_prescaler()
754 if (ctx->rotation) { in gsc_set_prescaler()
755 dst_w = dst->h; in gsc_set_prescaler()
756 dst_h = dst->w; in gsc_set_prescaler()
758 dst_w = dst->w; in gsc_set_prescaler()
759 dst_h = dst->h; in gsc_set_prescaler()
762 ret = gsc_get_ratio_shift(ctx, src_w, dst_w, &sc->pre_hratio); in gsc_set_prescaler()
764 DRM_DEV_ERROR(ctx->dev, "failed to get ratio horizontal.\n"); in gsc_set_prescaler()
768 ret = gsc_get_ratio_shift(ctx, src_h, dst_h, &sc->pre_vratio); in gsc_set_prescaler()
770 DRM_DEV_ERROR(ctx->dev, "failed to get ratio vertical.\n"); in gsc_set_prescaler()
774 DRM_DEV_DEBUG_KMS(ctx->dev, "pre_hratio[%d]pre_vratio[%d]\n", in gsc_set_prescaler()
775 sc->pre_hratio, sc->pre_vratio); in gsc_set_prescaler()
777 sc->main_hratio = (src_w << 16) / dst_w; in gsc_set_prescaler()
778 sc->main_vratio = (src_h << 16) / dst_h; in gsc_set_prescaler()
780 DRM_DEV_DEBUG_KMS(ctx->dev, "main_hratio[%ld]main_vratio[%ld]\n", in gsc_set_prescaler()
781 sc->main_hratio, sc->main_vratio); in gsc_set_prescaler()
783 gsc_get_prescaler_shfactor(sc->pre_hratio, sc->pre_vratio, in gsc_set_prescaler()
784 &sc->pre_shfactor); in gsc_set_prescaler()
786 DRM_DEV_DEBUG_KMS(ctx->dev, "pre_shfactor[%d]\n", sc->pre_shfactor); in gsc_set_prescaler()
788 cfg = (GSC_PRESC_SHFACTOR(sc->pre_shfactor) | in gsc_set_prescaler()
789 GSC_PRESC_H_RATIO(sc->pre_hratio) | in gsc_set_prescaler()
790 GSC_PRESC_V_RATIO(sc->pre_vratio)); in gsc_set_prescaler()
852 DRM_DEV_DEBUG_KMS(ctx->dev, "main_hratio[%ld]main_vratio[%ld]\n", in gsc_set_scaler()
853 sc->main_hratio, sc->main_vratio); in gsc_set_scaler()
855 gsc_set_h_coef(ctx, sc->main_hratio); in gsc_set_scaler()
856 cfg = GSC_MAIN_H_RATIO_VALUE(sc->main_hratio); in gsc_set_scaler()
859 gsc_set_v_coef(ctx, sc->main_vratio); in gsc_set_scaler()
860 cfg = GSC_MAIN_V_RATIO_VALUE(sc->main_vratio); in gsc_set_scaler()
867 struct gsc_scaler *sc = &ctx->sc; in gsc_dst_set_size()
871 cfg = (GSC_DSTIMG_OFFSET_X(buf->rect.x) | in gsc_dst_set_size()
872 GSC_DSTIMG_OFFSET_Y(buf->rect.y)); in gsc_dst_set_size()
876 if (ctx->rotation) in gsc_dst_set_size()
877 cfg = (GSC_SCALED_WIDTH(buf->rect.h) | in gsc_dst_set_size()
878 GSC_SCALED_HEIGHT(buf->rect.w)); in gsc_dst_set_size()
880 cfg = (GSC_SCALED_WIDTH(buf->rect.w) | in gsc_dst_set_size()
881 GSC_SCALED_HEIGHT(buf->rect.h)); in gsc_dst_set_size()
887 cfg |= GSC_DSTIMG_WIDTH(buf->buf.pitch[0] / buf->format->cpp[0]) | in gsc_dst_set_size()
888 GSC_DSTIMG_HEIGHT(buf->buf.height); in gsc_dst_set_size()
894 if (buf->rect.w >= GSC_WIDTH_ITU_709) in gsc_dst_set_size()
895 if (sc->range) in gsc_dst_set_size()
900 if (sc->range) in gsc_dst_set_size()
917 buf_num--; in gsc_dst_get_buf_seq()
919 DRM_DEV_DEBUG_KMS(ctx->dev, "buf_num[%d]\n", buf_num); in gsc_dst_get_buf_seq()
954 gsc_write(buf->dma_addr[0], GSC_OUT_BASE_ADDR_Y(buf_id)); in gsc_dst_set_addr()
955 gsc_write(buf->dma_addr[1], GSC_OUT_BASE_ADDR_CB(buf_id)); in gsc_dst_set_addr()
956 gsc_write(buf->dma_addr[2], GSC_OUT_BASE_ADDR_CR(buf_id)); in gsc_dst_set_addr()
966 DRM_DEV_DEBUG_KMS(ctx->dev, "gsc id[%d]\n", ctx->id); in gsc_get_src_buf_index()
978 DRM_DEV_DEBUG_KMS(ctx->dev, "cfg[0x%x]curr_index[%d]buf_id[%d]\n", cfg, in gsc_get_src_buf_index()
982 DRM_DEV_ERROR(ctx->dev, "failed to get in buffer index.\n"); in gsc_get_src_buf_index()
983 return -EINVAL; in gsc_get_src_buf_index()
996 DRM_DEV_DEBUG_KMS(ctx->dev, "gsc id[%d]\n", ctx->id); in gsc_get_dst_buf_index()
1009 DRM_DEV_ERROR(ctx->dev, "failed to get out buffer index.\n"); in gsc_get_dst_buf_index()
1010 return -EINVAL; in gsc_get_dst_buf_index()
1015 DRM_DEV_DEBUG_KMS(ctx->dev, "cfg[0x%x]curr_index[%d]buf_id[%d]\n", cfg, in gsc_get_dst_buf_index()
1027 DRM_DEV_DEBUG_KMS(ctx->dev, "gsc id[%d]\n", ctx->id); in gsc_irq_handler()
1031 dev_err(ctx->dev, "occurred overflow at %d, status 0x%x.\n", in gsc_irq_handler()
1032 ctx->id, status); in gsc_irq_handler()
1033 err = -EINVAL; in gsc_irq_handler()
1039 dev_dbg(ctx->dev, "occurred frame done at %d, status 0x%x.\n", in gsc_irq_handler()
1040 ctx->id, status); in gsc_irq_handler()
1045 DRM_DEV_DEBUG_KMS(ctx->dev, "buf_id_src[%d]buf_id_dst[%d]\n", in gsc_irq_handler()
1049 err = -EINVAL; in gsc_irq_handler()
1052 if (ctx->task) { in gsc_irq_handler()
1053 struct exynos_drm_ipp_task *task = ctx->task; in gsc_irq_handler()
1055 ctx->task = NULL; in gsc_irq_handler()
1056 pm_runtime_mark_last_busy(ctx->dev); in gsc_irq_handler()
1057 pm_runtime_put_autosuspend(ctx->dev); in gsc_irq_handler()
1066 struct gsc_scaler *sc = &ctx->sc; in gsc_reset()
1072 dev_err(ctx->dev, "failed to reset hardware.\n"); in gsc_reset()
1077 memset(&ctx->sc, 0x0, sizeof(ctx->sc)); in gsc_reset()
1078 sc->range = true; in gsc_reset()
1107 gsc_set_scaler(ctx, &ctx->sc); in gsc_start()
1120 ret = pm_runtime_resume_and_get(ctx->dev); in gsc_commit()
1122 dev_err(ctx->dev, "failed to enable GScaler device.\n"); in gsc_commit()
1126 ctx->task = task; in gsc_commit()
1130 pm_runtime_put_autosuspend(ctx->dev); in gsc_commit()
1131 ctx->task = NULL; in gsc_commit()
1135 gsc_src_set_fmt(ctx, task->src.buf.fourcc, task->src.buf.modifier); in gsc_commit()
1136 gsc_src_set_transf(ctx, task->transform.rotation); in gsc_commit()
1137 gsc_src_set_size(ctx, &task->src); in gsc_commit()
1138 gsc_src_set_addr(ctx, 0, &task->src); in gsc_commit()
1139 gsc_dst_set_fmt(ctx, task->dst.buf.fourcc, task->dst.buf.modifier); in gsc_commit()
1140 gsc_dst_set_size(ctx, &task->dst); in gsc_commit()
1141 gsc_dst_set_addr(ctx, 0, &task->dst); in gsc_commit()
1142 gsc_set_prescaler(ctx, &ctx->sc, &task->src.rect, &task->dst.rect); in gsc_commit()
1155 if (ctx->task) { in gsc_abort()
1156 struct exynos_drm_ipp_task *task = ctx->task; in gsc_abort()
1158 ctx->task = NULL; in gsc_abort()
1159 pm_runtime_mark_last_busy(ctx->dev); in gsc_abort()
1160 pm_runtime_put_autosuspend(ctx->dev); in gsc_abort()
1161 exynos_drm_ipp_task_done(task, -EIO); in gsc_abort()
1174 struct exynos_drm_ipp *ipp = &ctx->ipp; in gsc_bind()
1176 ctx->drm_dev = drm_dev; in gsc_bind()
1177 ipp->drm_dev = drm_dev; in gsc_bind()
1178 exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv); in gsc_bind()
1183 ctx->formats, ctx->num_formats, "gsc"); in gsc_bind()
1195 struct exynos_drm_ipp *ipp = &ctx->ipp; in gsc_unbind()
1198 exynos_drm_unregister_dma(drm_dev, dev, &ctx->dma_priv); in gsc_unbind()
1220 struct device *dev = &pdev->dev; in gsc_probe()
1228 return -ENOMEM; in gsc_probe()
1231 ctx->dev = dev; in gsc_probe()
1232 ctx->num_clocks = driver_data->num_clocks; in gsc_probe()
1233 ctx->clk_names = driver_data->clk_names; in gsc_probe()
1239 return -ENOMEM; in gsc_probe()
1246 formats[i].limits = driver_data->limits; in gsc_probe()
1247 formats[i].num_limits = driver_data->num_limits; in gsc_probe()
1256 formats[j].limits = driver_data->limits; in gsc_probe()
1257 formats[j].num_limits = driver_data->num_limits; in gsc_probe()
1260 ctx->formats = formats; in gsc_probe()
1261 ctx->num_formats = num_formats; in gsc_probe()
1264 for (i = 0; i < ctx->num_clocks; i++) { in gsc_probe()
1265 ctx->clocks[i] = devm_clk_get(dev, ctx->clk_names[i]); in gsc_probe()
1266 if (IS_ERR(ctx->clocks[i])) { in gsc_probe()
1268 ctx->clk_names[i]); in gsc_probe()
1269 return PTR_ERR(ctx->clocks[i]); in gsc_probe()
1273 ctx->regs = devm_platform_ioremap_resource(pdev, 0); in gsc_probe()
1274 if (IS_ERR(ctx->regs)) in gsc_probe()
1275 return PTR_ERR(ctx->regs); in gsc_probe()
1278 ctx->irq = platform_get_irq(pdev, 0); in gsc_probe()
1279 if (ctx->irq < 0) in gsc_probe()
1280 return ctx->irq; in gsc_probe()
1282 ret = devm_request_irq(dev, ctx->irq, gsc_irq_handler, 0, in gsc_probe()
1290 ctx->id = pdev->id; in gsc_probe()
1302 dev_info(dev, "drm gsc registered successfully.\n"); in gsc_probe()
1314 struct device *dev = &pdev->dev; in gsc_remove()
1326 DRM_DEV_DEBUG_KMS(dev, "id[%d]\n", ctx->id); in gsc_runtime_suspend()
1328 for (i = ctx->num_clocks - 1; i >= 0; i--) in gsc_runtime_suspend()
1329 clk_disable_unprepare(ctx->clocks[i]); in gsc_runtime_suspend()
1339 DRM_DEV_DEBUG_KMS(dev, "id[%d]\n", ctx->id); in gsc_runtime_resume()
1341 for (i = 0; i < ctx->num_clocks; i++) { in gsc_runtime_resume()
1342 ret = clk_prepare_enable(ctx->clocks[i]); in gsc_runtime_resume()
1344 while (--i >= 0) in gsc_runtime_resume()
1345 clk_disable_unprepare(ctx->clocks[i]); in gsc_runtime_resume()
1405 .compatible = "samsung,exynos5-gsc",
1408 .compatible = "samsung,exynos5250-gsc",
1411 .compatible = "samsung,exynos5420-gsc",
1414 .compatible = "samsung,exynos5433-gsc",
1425 .name = "exynos-drm-gsc",