Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) 2012-2014 Mentor Graphics Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright 2005-2012 Freescale Semiconductor, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/bitrev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/sizes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "ipu-prv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) /* IC Register Offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define IC_CONF                 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define IC_PRP_ENC_RSC          0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define IC_PRP_VF_RSC           0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define IC_PP_RSC               0x000C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define IC_CMBP_1               0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define IC_CMBP_2               0x0014
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define IC_IDMAC_1              0x0018
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define IC_IDMAC_2              0x001C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define IC_IDMAC_3              0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define IC_IDMAC_4              0x0024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) /* IC Register Fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define IC_CONF_PRPENC_EN       (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define IC_CONF_PRPENC_CSC1     (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define IC_CONF_PRPENC_ROT_EN   (1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define IC_CONF_PRPVF_EN        (1 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define IC_CONF_PRPVF_CSC1      (1 << 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define IC_CONF_PRPVF_CSC2      (1 << 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define IC_CONF_PRPVF_CMB       (1 << 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define IC_CONF_PRPVF_ROT_EN    (1 << 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define IC_CONF_PP_EN           (1 << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define IC_CONF_PP_CSC1         (1 << 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define IC_CONF_PP_CSC2         (1 << 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define IC_CONF_PP_CMB          (1 << 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define IC_CONF_PP_ROT_EN       (1 << 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define IC_CONF_IC_GLB_LOC_A    (1 << 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define IC_CONF_KEY_COLOR_EN    (1 << 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define IC_CONF_RWS_EN          (1 << 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define IC_CONF_CSI_MEM_WR_EN   (1 << 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define IC_IDMAC_1_CB0_BURST_16         (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define IC_IDMAC_1_CB1_BURST_16         (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define IC_IDMAC_1_CB2_BURST_16         (1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define IC_IDMAC_1_CB3_BURST_16         (1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define IC_IDMAC_1_CB4_BURST_16         (1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define IC_IDMAC_1_CB5_BURST_16         (1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define IC_IDMAC_1_CB6_BURST_16         (1 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define IC_IDMAC_1_CB7_BURST_16         (1 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define IC_IDMAC_1_PRPENC_ROT_MASK      (0x7 << 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define IC_IDMAC_1_PRPENC_ROT_OFFSET    11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define IC_IDMAC_1_PRPVF_ROT_MASK       (0x7 << 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define IC_IDMAC_1_PRPVF_ROT_OFFSET     14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #define IC_IDMAC_1_PP_ROT_MASK          (0x7 << 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define IC_IDMAC_1_PP_ROT_OFFSET        17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define IC_IDMAC_1_PP_FLIP_RS           (1 << 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #define IC_IDMAC_1_PRPVF_FLIP_RS        (1 << 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define IC_IDMAC_1_PRPENC_FLIP_RS       (1 << 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define IC_IDMAC_2_PRPENC_HEIGHT_MASK   (0x3ff << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define IC_IDMAC_2_PRPENC_HEIGHT_OFFSET 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define IC_IDMAC_2_PRPVF_HEIGHT_MASK    (0x3ff << 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define IC_IDMAC_2_PRPVF_HEIGHT_OFFSET  10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define IC_IDMAC_2_PP_HEIGHT_MASK       (0x3ff << 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) #define IC_IDMAC_2_PP_HEIGHT_OFFSET     20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #define IC_IDMAC_3_PRPENC_WIDTH_MASK    (0x3ff << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) #define IC_IDMAC_3_PRPENC_WIDTH_OFFSET  0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) #define IC_IDMAC_3_PRPVF_WIDTH_MASK     (0x3ff << 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #define IC_IDMAC_3_PRPVF_WIDTH_OFFSET   10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #define IC_IDMAC_3_PP_WIDTH_MASK        (0x3ff << 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) #define IC_IDMAC_3_PP_WIDTH_OFFSET      20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) struct ic_task_regoffs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	u32 rsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	u32 tpmem_csc[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) struct ic_task_bitfields {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	u32 ic_conf_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	u32 ic_conf_rot_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	u32 ic_conf_cmb_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	u32 ic_conf_csc1_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	u32 ic_conf_csc2_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	u32 ic_cmb_galpha_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) static const struct ic_task_regoffs ic_task_reg[IC_NUM_TASKS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	[IC_TASK_ENCODER] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		.rsc = IC_PRP_ENC_RSC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		.tpmem_csc = {0x2008, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	[IC_TASK_VIEWFINDER] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		.rsc = IC_PRP_VF_RSC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		.tpmem_csc = {0x4028, 0x4040},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	[IC_TASK_POST_PROCESSOR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		.rsc = IC_PP_RSC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		.tpmem_csc = {0x6060, 0x6078},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static const struct ic_task_bitfields ic_task_bit[IC_NUM_TASKS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	[IC_TASK_ENCODER] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		.ic_conf_en = IC_CONF_PRPENC_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		.ic_conf_rot_en = IC_CONF_PRPENC_ROT_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		.ic_conf_cmb_en = 0,    /* NA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		.ic_conf_csc1_en = IC_CONF_PRPENC_CSC1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		.ic_conf_csc2_en = 0,   /* NA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		.ic_cmb_galpha_bit = 0, /* NA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	[IC_TASK_VIEWFINDER] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		.ic_conf_en = IC_CONF_PRPVF_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		.ic_conf_rot_en = IC_CONF_PRPVF_ROT_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		.ic_conf_cmb_en = IC_CONF_PRPVF_CMB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		.ic_conf_csc1_en = IC_CONF_PRPVF_CSC1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		.ic_conf_csc2_en = IC_CONF_PRPVF_CSC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		.ic_cmb_galpha_bit = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	[IC_TASK_POST_PROCESSOR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		.ic_conf_en = IC_CONF_PP_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		.ic_conf_rot_en = IC_CONF_PP_ROT_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		.ic_conf_cmb_en = IC_CONF_PP_CMB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		.ic_conf_csc1_en = IC_CONF_PP_CSC1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		.ic_conf_csc2_en = IC_CONF_PP_CSC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		.ic_cmb_galpha_bit = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct ipu_ic_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct ipu_ic {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	enum ipu_ic_task task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	const struct ic_task_regoffs *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	const struct ic_task_bitfields *bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	struct ipu_ic_colorspace in_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	struct ipu_ic_colorspace g_in_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	struct ipu_ic_colorspace out_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	bool graphics;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	bool rotation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	bool in_use;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	struct ipu_ic_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct ipu_ic_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	void __iomem *tpmem_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	struct ipu_soc *ipu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	int use_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	int irt_use_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	struct ipu_ic task[IC_NUM_TASKS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static inline u32 ipu_ic_read(struct ipu_ic *ic, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	return readl(ic->priv->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static inline void ipu_ic_write(struct ipu_ic *ic, u32 value, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	writel(value, ic->priv->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static int init_csc(struct ipu_ic *ic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		    const struct ipu_ic_csc *csc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		    int csc_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	struct ipu_ic_priv *priv = ic->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	u32 __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	const u16 (*c)[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	const u16 *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	u32 param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	base = (u32 __iomem *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		(priv->tpmem_base + ic->reg->tpmem_csc[csc_index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	/* Cast to unsigned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	c = (const u16 (*)[3])csc->params.coeff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	a = (const u16 *)csc->params.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	param = ((a[0] & 0x1f) << 27) | ((c[0][0] & 0x1ff) << 18) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		((c[1][1] & 0x1ff) << 9) | (c[2][2] & 0x1ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	writel(param, base++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	param = ((a[0] & 0x1fe0) >> 5) | (csc->params.scale << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		(csc->params.sat << 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	writel(param, base++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	param = ((a[1] & 0x1f) << 27) | ((c[0][1] & 0x1ff) << 18) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		((c[1][0] & 0x1ff) << 9) | (c[2][0] & 0x1ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	writel(param, base++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	param = ((a[1] & 0x1fe0) >> 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	writel(param, base++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	param = ((a[2] & 0x1f) << 27) | ((c[0][2] & 0x1ff) << 18) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		((c[1][2] & 0x1ff) << 9) | (c[2][1] & 0x1ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	writel(param, base++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	param = ((a[2] & 0x1fe0) >> 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	writel(param, base++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static int calc_resize_coeffs(struct ipu_ic *ic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			      u32 in_size, u32 out_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 			      u32 *resize_coeff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 			      u32 *downsize_coeff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	struct ipu_ic_priv *priv = ic->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	struct ipu_soc *ipu = priv->ipu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	u32 temp_size, temp_downsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	 * Input size cannot be more than 4096, and output size cannot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	 * be more than 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	if (in_size > 4096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		dev_err(ipu->dev, "Unsupported resize (in_size > 4096)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	if (out_size > 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		dev_err(ipu->dev, "Unsupported resize (out_size > 1024)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	/* Cannot downsize more than 4:1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	if ((out_size << 2) < in_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		dev_err(ipu->dev, "Unsupported downsize\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	/* Compute downsizing coefficient */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	temp_downsize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	temp_size = in_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	while (((temp_size > 1024) || (temp_size >= out_size * 2)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	       (temp_downsize < 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		temp_size >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		temp_downsize++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	*downsize_coeff = temp_downsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	 * compute resizing coefficient using the following equation:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	 * resize_coeff = M * (SI - 1) / (SO - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	 * where M = 2^13, SI = input size, SO = output size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	*resize_coeff = (8192L * (temp_size - 1)) / (out_size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	if (*resize_coeff >= 16384L) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		dev_err(ipu->dev, "Warning! Overflow on resize coeff.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		*resize_coeff = 0x3FFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) void ipu_ic_task_enable(struct ipu_ic *ic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	struct ipu_ic_priv *priv = ic->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	u32 ic_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	ic_conf = ipu_ic_read(ic, IC_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	ic_conf |= ic->bit->ic_conf_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	if (ic->rotation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		ic_conf |= ic->bit->ic_conf_rot_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	if (ic->in_cs.cs != ic->out_cs.cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		ic_conf |= ic->bit->ic_conf_csc1_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	if (ic->graphics) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		ic_conf |= ic->bit->ic_conf_cmb_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		ic_conf |= ic->bit->ic_conf_csc1_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		if (ic->g_in_cs.cs != ic->out_cs.cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 			ic_conf |= ic->bit->ic_conf_csc2_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	ipu_ic_write(ic, ic_conf, IC_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) EXPORT_SYMBOL_GPL(ipu_ic_task_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) void ipu_ic_task_disable(struct ipu_ic *ic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	struct ipu_ic_priv *priv = ic->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	u32 ic_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	ic_conf = ipu_ic_read(ic, IC_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	ic_conf &= ~(ic->bit->ic_conf_en |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		     ic->bit->ic_conf_csc1_en |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		     ic->bit->ic_conf_rot_en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	if (ic->bit->ic_conf_csc2_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		ic_conf &= ~ic->bit->ic_conf_csc2_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	if (ic->bit->ic_conf_cmb_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		ic_conf &= ~ic->bit->ic_conf_cmb_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	ipu_ic_write(ic, ic_conf, IC_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) EXPORT_SYMBOL_GPL(ipu_ic_task_disable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) int ipu_ic_task_graphics_init(struct ipu_ic *ic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 			      const struct ipu_ic_colorspace *g_in_cs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 			      bool galpha_en, u32 galpha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 			      bool colorkey_en, u32 colorkey)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	struct ipu_ic_priv *priv = ic->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	struct ipu_ic_csc csc2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	u32 reg, ic_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	if (ic->task == IC_TASK_ENCODER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	ic_conf = ipu_ic_read(ic, IC_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	if (!(ic_conf & ic->bit->ic_conf_csc1_en)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		struct ipu_ic_csc csc1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		ret = ipu_ic_calc_csc(&csc1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 				      V4L2_YCBCR_ENC_601,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 				      V4L2_QUANTIZATION_FULL_RANGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 				      IPUV3_COLORSPACE_RGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 				      V4L2_YCBCR_ENC_601,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 				      V4L2_QUANTIZATION_FULL_RANGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 				      IPUV3_COLORSPACE_RGB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 			goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		/* need transparent CSC1 conversion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		ret = init_csc(ic, &csc1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 			goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	ic->g_in_cs = *g_in_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	csc2.in_cs = ic->g_in_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	csc2.out_cs = ic->out_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	ret = __ipu_ic_calc_csc(&csc2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	ret = init_csc(ic, &csc2, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	if (galpha_en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		ic_conf |= IC_CONF_IC_GLB_LOC_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		reg = ipu_ic_read(ic, IC_CMBP_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		reg &= ~(0xff << ic->bit->ic_cmb_galpha_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		reg |= (galpha << ic->bit->ic_cmb_galpha_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		ipu_ic_write(ic, reg, IC_CMBP_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		ic_conf &= ~IC_CONF_IC_GLB_LOC_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	if (colorkey_en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		ic_conf |= IC_CONF_KEY_COLOR_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		ipu_ic_write(ic, colorkey, IC_CMBP_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		ic_conf &= ~IC_CONF_KEY_COLOR_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	ipu_ic_write(ic, ic_conf, IC_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	ic->graphics = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) EXPORT_SYMBOL_GPL(ipu_ic_task_graphics_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) int ipu_ic_task_init_rsc(struct ipu_ic *ic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 			 const struct ipu_ic_csc *csc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 			 int in_width, int in_height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 			 int out_width, int out_height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 			 u32 rsc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	struct ipu_ic_priv *priv = ic->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	u32 downsize_coeff, resize_coeff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	if (!rsc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		/* Setup vertical resizing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		ret = calc_resize_coeffs(ic, in_height, out_height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 					 &resize_coeff, &downsize_coeff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		rsc = (downsize_coeff << 30) | (resize_coeff << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		/* Setup horizontal resizing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		ret = calc_resize_coeffs(ic, in_width, out_width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 					 &resize_coeff, &downsize_coeff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		rsc |= (downsize_coeff << 14) | resize_coeff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	ipu_ic_write(ic, rsc, ic->reg->rsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	/* Setup color space conversion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	ic->in_cs = csc->in_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	ic->out_cs = csc->out_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	ret = init_csc(ic, csc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) int ipu_ic_task_init(struct ipu_ic *ic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		     const struct ipu_ic_csc *csc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		     int in_width, int in_height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		     int out_width, int out_height)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	return ipu_ic_task_init_rsc(ic, csc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 				    in_width, in_height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 				    out_width, out_height, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) EXPORT_SYMBOL_GPL(ipu_ic_task_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) int ipu_ic_task_idma_init(struct ipu_ic *ic, struct ipuv3_channel *channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 			  u32 width, u32 height, int burst_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 			  enum ipu_rotate_mode rot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	struct ipu_ic_priv *priv = ic->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	struct ipu_soc *ipu = priv->ipu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	u32 ic_idmac_1, ic_idmac_2, ic_idmac_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	u32 temp_rot = bitrev8(rot) >> 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	bool need_hor_flip = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	if ((burst_size != 8) && (burst_size != 16)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		dev_err(ipu->dev, "Illegal burst length for IC\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	width--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	height--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	if (temp_rot & 0x2)	/* Need horizontal flip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		need_hor_flip = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	ic_idmac_1 = ipu_ic_read(ic, IC_IDMAC_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	ic_idmac_2 = ipu_ic_read(ic, IC_IDMAC_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	ic_idmac_3 = ipu_ic_read(ic, IC_IDMAC_3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	switch (channel->num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	case IPUV3_CHANNEL_IC_PP_MEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		if (burst_size == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 			ic_idmac_1 |= IC_IDMAC_1_CB2_BURST_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 			ic_idmac_1 &= ~IC_IDMAC_1_CB2_BURST_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		if (need_hor_flip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 			ic_idmac_1 |= IC_IDMAC_1_PP_FLIP_RS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 			ic_idmac_1 &= ~IC_IDMAC_1_PP_FLIP_RS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		ic_idmac_2 &= ~IC_IDMAC_2_PP_HEIGHT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		ic_idmac_2 |= height << IC_IDMAC_2_PP_HEIGHT_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		ic_idmac_3 &= ~IC_IDMAC_3_PP_WIDTH_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		ic_idmac_3 |= width << IC_IDMAC_3_PP_WIDTH_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	case IPUV3_CHANNEL_MEM_IC_PP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		if (burst_size == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 			ic_idmac_1 |= IC_IDMAC_1_CB5_BURST_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 			ic_idmac_1 &= ~IC_IDMAC_1_CB5_BURST_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	case IPUV3_CHANNEL_MEM_ROT_PP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		ic_idmac_1 &= ~IC_IDMAC_1_PP_ROT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		ic_idmac_1 |= temp_rot << IC_IDMAC_1_PP_ROT_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	case IPUV3_CHANNEL_MEM_IC_PRP_VF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		if (burst_size == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 			ic_idmac_1 |= IC_IDMAC_1_CB6_BURST_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 			ic_idmac_1 &= ~IC_IDMAC_1_CB6_BURST_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	case IPUV3_CHANNEL_IC_PRP_ENC_MEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		if (burst_size == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 			ic_idmac_1 |= IC_IDMAC_1_CB0_BURST_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 			ic_idmac_1 &= ~IC_IDMAC_1_CB0_BURST_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		if (need_hor_flip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 			ic_idmac_1 |= IC_IDMAC_1_PRPENC_FLIP_RS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 			ic_idmac_1 &= ~IC_IDMAC_1_PRPENC_FLIP_RS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		ic_idmac_2 &= ~IC_IDMAC_2_PRPENC_HEIGHT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		ic_idmac_2 |= height << IC_IDMAC_2_PRPENC_HEIGHT_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		ic_idmac_3 &= ~IC_IDMAC_3_PRPENC_WIDTH_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		ic_idmac_3 |= width << IC_IDMAC_3_PRPENC_WIDTH_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	case IPUV3_CHANNEL_MEM_ROT_ENC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		ic_idmac_1 &= ~IC_IDMAC_1_PRPENC_ROT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		ic_idmac_1 |= temp_rot << IC_IDMAC_1_PRPENC_ROT_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	case IPUV3_CHANNEL_IC_PRP_VF_MEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		if (burst_size == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 			ic_idmac_1 |= IC_IDMAC_1_CB1_BURST_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 			ic_idmac_1 &= ~IC_IDMAC_1_CB1_BURST_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		if (need_hor_flip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 			ic_idmac_1 |= IC_IDMAC_1_PRPVF_FLIP_RS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 			ic_idmac_1 &= ~IC_IDMAC_1_PRPVF_FLIP_RS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		ic_idmac_2 &= ~IC_IDMAC_2_PRPVF_HEIGHT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		ic_idmac_2 |= height << IC_IDMAC_2_PRPVF_HEIGHT_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		ic_idmac_3 &= ~IC_IDMAC_3_PRPVF_WIDTH_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		ic_idmac_3 |= width << IC_IDMAC_3_PRPVF_WIDTH_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	case IPUV3_CHANNEL_MEM_ROT_VF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		ic_idmac_1 &= ~IC_IDMAC_1_PRPVF_ROT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		ic_idmac_1 |= temp_rot << IC_IDMAC_1_PRPVF_ROT_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	case IPUV3_CHANNEL_G_MEM_IC_PRP_VF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		if (burst_size == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 			ic_idmac_1 |= IC_IDMAC_1_CB3_BURST_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 			ic_idmac_1 &= ~IC_IDMAC_1_CB3_BURST_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	case IPUV3_CHANNEL_G_MEM_IC_PP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		if (burst_size == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 			ic_idmac_1 |= IC_IDMAC_1_CB4_BURST_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 			ic_idmac_1 &= ~IC_IDMAC_1_CB4_BURST_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	case IPUV3_CHANNEL_VDI_MEM_IC_VF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		if (burst_size == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 			ic_idmac_1 |= IC_IDMAC_1_CB7_BURST_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 			ic_idmac_1 &= ~IC_IDMAC_1_CB7_BURST_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	ipu_ic_write(ic, ic_idmac_1, IC_IDMAC_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	ipu_ic_write(ic, ic_idmac_2, IC_IDMAC_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	ipu_ic_write(ic, ic_idmac_3, IC_IDMAC_3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	if (ipu_rot_mode_is_irt(rot))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		ic->rotation = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) EXPORT_SYMBOL_GPL(ipu_ic_task_idma_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static void ipu_irt_enable(struct ipu_ic *ic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	struct ipu_ic_priv *priv = ic->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	if (!priv->irt_use_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		ipu_module_enable(priv->ipu, IPU_CONF_ROT_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	priv->irt_use_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) static void ipu_irt_disable(struct ipu_ic *ic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	struct ipu_ic_priv *priv = ic->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	if (priv->irt_use_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		if (!--priv->irt_use_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 			ipu_module_disable(priv->ipu, IPU_CONF_ROT_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) int ipu_ic_enable(struct ipu_ic *ic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	struct ipu_ic_priv *priv = ic->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	if (!priv->use_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 		ipu_module_enable(priv->ipu, IPU_CONF_IC_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	priv->use_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	if (ic->rotation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		ipu_irt_enable(ic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) EXPORT_SYMBOL_GPL(ipu_ic_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) int ipu_ic_disable(struct ipu_ic *ic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	struct ipu_ic_priv *priv = ic->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	priv->use_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	if (!priv->use_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 		ipu_module_disable(priv->ipu, IPU_CONF_IC_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	if (priv->use_count < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		priv->use_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	if (ic->rotation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		ipu_irt_disable(ic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	ic->rotation = ic->graphics = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) EXPORT_SYMBOL_GPL(ipu_ic_disable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct ipu_ic *ipu_ic_get(struct ipu_soc *ipu, enum ipu_ic_task task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	struct ipu_ic_priv *priv = ipu->ic_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	struct ipu_ic *ic, *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	if (task >= IC_NUM_TASKS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	ic = &priv->task[task];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	if (ic->in_use) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 		ret = ERR_PTR(-EBUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 		goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	ic->in_use = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	ret = ic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) EXPORT_SYMBOL_GPL(ipu_ic_get);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) void ipu_ic_put(struct ipu_ic *ic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	struct ipu_ic_priv *priv = ic->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	ic->in_use = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) EXPORT_SYMBOL_GPL(ipu_ic_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) int ipu_ic_init(struct ipu_soc *ipu, struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 		unsigned long base, unsigned long tpmem_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	struct ipu_ic_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	ipu->ic_priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	spin_lock_init(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	priv->base = devm_ioremap(dev, base, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	if (!priv->base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	priv->tpmem_base = devm_ioremap(dev, tpmem_base, SZ_64K);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	if (!priv->tpmem_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	dev_dbg(dev, "IC base: 0x%08lx remapped to %p\n", base, priv->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	priv->ipu = ipu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	for (i = 0; i < IC_NUM_TASKS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 		priv->task[i].task = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 		priv->task[i].priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 		priv->task[i].reg = &ic_task_reg[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 		priv->task[i].bit = &ic_task_bit[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) void ipu_ic_exit(struct ipu_soc *ipu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) void ipu_ic_dump(struct ipu_ic *ic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	struct ipu_ic_priv *priv = ic->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	struct ipu_soc *ipu = priv->ipu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	dev_dbg(ipu->dev, "IC_CONF = \t0x%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 		ipu_ic_read(ic, IC_CONF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	dev_dbg(ipu->dev, "IC_PRP_ENC_RSC = \t0x%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 		ipu_ic_read(ic, IC_PRP_ENC_RSC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	dev_dbg(ipu->dev, "IC_PRP_VF_RSC = \t0x%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 		ipu_ic_read(ic, IC_PRP_VF_RSC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	dev_dbg(ipu->dev, "IC_PP_RSC = \t0x%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 		ipu_ic_read(ic, IC_PP_RSC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	dev_dbg(ipu->dev, "IC_CMBP_1 = \t0x%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 		ipu_ic_read(ic, IC_CMBP_1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	dev_dbg(ipu->dev, "IC_CMBP_2 = \t0x%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 		ipu_ic_read(ic, IC_CMBP_2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 	dev_dbg(ipu->dev, "IC_IDMAC_1 = \t0x%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 		ipu_ic_read(ic, IC_IDMAC_1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	dev_dbg(ipu->dev, "IC_IDMAC_2 = \t0x%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 		ipu_ic_read(ic, IC_IDMAC_2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	dev_dbg(ipu->dev, "IC_IDMAC_3 = \t0x%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 		ipu_ic_read(ic, IC_IDMAC_3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	dev_dbg(ipu->dev, "IC_IDMAC_4 = \t0x%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 		ipu_ic_read(ic, IC_IDMAC_4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) EXPORT_SYMBOL_GPL(ipu_ic_dump);