162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Samsung S5P G2D - 2D Graphics Accelerator Driver 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2011 Samsung Electronics Co., Ltd. 662306a36Sopenharmony_ci * Kamil Debski, <k.debski@samsung.com> 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/io.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include "g2d.h" 1262306a36Sopenharmony_ci#include "g2d-regs.h" 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#define w(x, a) writel((x), d->regs + (a)) 1562306a36Sopenharmony_ci#define r(a) readl(d->regs + (a)) 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci/* g2d_reset clears all g2d registers */ 1862306a36Sopenharmony_civoid g2d_reset(struct g2d_dev *d) 1962306a36Sopenharmony_ci{ 2062306a36Sopenharmony_ci w(1, SOFT_RESET_REG); 2162306a36Sopenharmony_ci} 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_civoid g2d_set_src_size(struct g2d_dev *d, struct g2d_frame *f) 2462306a36Sopenharmony_ci{ 2562306a36Sopenharmony_ci u32 n; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci w(0, SRC_SELECT_REG); 2862306a36Sopenharmony_ci w(f->stride & 0xFFFF, SRC_STRIDE_REG); 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci n = f->o_height & 0xFFF; 3162306a36Sopenharmony_ci n <<= 16; 3262306a36Sopenharmony_ci n |= f->o_width & 0xFFF; 3362306a36Sopenharmony_ci w(n, SRC_LEFT_TOP_REG); 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci n = f->bottom & 0xFFF; 3662306a36Sopenharmony_ci n <<= 16; 3762306a36Sopenharmony_ci n |= f->right & 0xFFF; 3862306a36Sopenharmony_ci w(n, SRC_RIGHT_BOTTOM_REG); 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci w(f->fmt->hw, SRC_COLOR_MODE_REG); 4162306a36Sopenharmony_ci} 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_civoid g2d_set_src_addr(struct g2d_dev *d, dma_addr_t a) 4462306a36Sopenharmony_ci{ 4562306a36Sopenharmony_ci w(a, SRC_BASE_ADDR_REG); 4662306a36Sopenharmony_ci} 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_civoid g2d_set_dst_size(struct g2d_dev *d, struct g2d_frame *f) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci u32 n; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci w(0, DST_SELECT_REG); 5362306a36Sopenharmony_ci w(f->stride & 0xFFFF, DST_STRIDE_REG); 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci n = f->o_height & 0xFFF; 5662306a36Sopenharmony_ci n <<= 16; 5762306a36Sopenharmony_ci n |= f->o_width & 0xFFF; 5862306a36Sopenharmony_ci w(n, DST_LEFT_TOP_REG); 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci n = f->bottom & 0xFFF; 6162306a36Sopenharmony_ci n <<= 16; 6262306a36Sopenharmony_ci n |= f->right & 0xFFF; 6362306a36Sopenharmony_ci w(n, DST_RIGHT_BOTTOM_REG); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci w(f->fmt->hw, DST_COLOR_MODE_REG); 6662306a36Sopenharmony_ci} 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_civoid g2d_set_dst_addr(struct g2d_dev *d, dma_addr_t a) 6962306a36Sopenharmony_ci{ 7062306a36Sopenharmony_ci w(a, DST_BASE_ADDR_REG); 7162306a36Sopenharmony_ci} 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_civoid g2d_set_rop4(struct g2d_dev *d, u32 r) 7462306a36Sopenharmony_ci{ 7562306a36Sopenharmony_ci w(r, ROP4_REG); 7662306a36Sopenharmony_ci} 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_civoid g2d_set_flip(struct g2d_dev *d, u32 r) 7962306a36Sopenharmony_ci{ 8062306a36Sopenharmony_ci w(r, SRC_MSK_DIRECT_REG); 8162306a36Sopenharmony_ci} 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_civoid g2d_set_v41_stretch(struct g2d_dev *d, struct g2d_frame *src, 8462306a36Sopenharmony_ci struct g2d_frame *dst) 8562306a36Sopenharmony_ci{ 8662306a36Sopenharmony_ci w(DEFAULT_SCALE_MODE, SRC_SCALE_CTRL_REG); 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci /* inversed scaling factor: src is numerator */ 8962306a36Sopenharmony_ci w((src->c_width << 16) / dst->c_width, SRC_XSCALE_REG); 9062306a36Sopenharmony_ci w((src->c_height << 16) / dst->c_height, SRC_YSCALE_REG); 9162306a36Sopenharmony_ci} 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_civoid g2d_set_cmd(struct g2d_dev *d, u32 c) 9462306a36Sopenharmony_ci{ 9562306a36Sopenharmony_ci w(c, BITBLT_COMMAND_REG); 9662306a36Sopenharmony_ci} 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_civoid g2d_start(struct g2d_dev *d) 9962306a36Sopenharmony_ci{ 10062306a36Sopenharmony_ci /* Clear cache */ 10162306a36Sopenharmony_ci if (d->variant->hw_rev == TYPE_G2D_3X) 10262306a36Sopenharmony_ci w(0x7, CACHECTL_REG); 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci /* Enable interrupt */ 10562306a36Sopenharmony_ci w(1, INTEN_REG); 10662306a36Sopenharmony_ci /* Start G2D engine */ 10762306a36Sopenharmony_ci w(1, BITBLT_START_REG); 10862306a36Sopenharmony_ci} 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_civoid g2d_clear_int(struct g2d_dev *d) 11162306a36Sopenharmony_ci{ 11262306a36Sopenharmony_ci w(1, INTC_PEND_REG); 11362306a36Sopenharmony_ci} 114