^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 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) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/bitrev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/sizes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <drm/drm_fourcc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "ipu-prv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) struct ipu_cpmem_word {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) u32 data[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) u32 res[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct ipu_ch_param {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct ipu_cpmem_word word[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct ipu_cpmem {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct ipu_ch_param __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) u32 module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) int use_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct ipu_soc *ipu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define IPU_CPMEM_WORD(word, ofs, size) ((((word) * 160 + (ofs)) << 8) | (size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define IPU_FIELD_UBO IPU_CPMEM_WORD(0, 46, 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define IPU_FIELD_VBO IPU_CPMEM_WORD(0, 68, 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define IPU_FIELD_IOX IPU_CPMEM_WORD(0, 90, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define IPU_FIELD_RDRW IPU_CPMEM_WORD(0, 94, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define IPU_FIELD_SO IPU_CPMEM_WORD(0, 113, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define IPU_FIELD_SLY IPU_CPMEM_WORD(1, 102, 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define IPU_FIELD_SLUV IPU_CPMEM_WORD(1, 128, 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define IPU_FIELD_XV IPU_CPMEM_WORD(0, 0, 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define IPU_FIELD_YV IPU_CPMEM_WORD(0, 10, 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define IPU_FIELD_XB IPU_CPMEM_WORD(0, 19, 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define IPU_FIELD_YB IPU_CPMEM_WORD(0, 32, 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define IPU_FIELD_NSB_B IPU_CPMEM_WORD(0, 44, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define IPU_FIELD_CF IPU_CPMEM_WORD(0, 45, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define IPU_FIELD_SX IPU_CPMEM_WORD(0, 46, 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define IPU_FIELD_SY IPU_CPMEM_WORD(0, 58, 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define IPU_FIELD_NS IPU_CPMEM_WORD(0, 69, 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define IPU_FIELD_SDX IPU_CPMEM_WORD(0, 79, 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define IPU_FIELD_SM IPU_CPMEM_WORD(0, 86, 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define IPU_FIELD_SCC IPU_CPMEM_WORD(0, 96, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define IPU_FIELD_SCE IPU_CPMEM_WORD(0, 97, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define IPU_FIELD_SDY IPU_CPMEM_WORD(0, 98, 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define IPU_FIELD_SDRX IPU_CPMEM_WORD(0, 105, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define IPU_FIELD_SDRY IPU_CPMEM_WORD(0, 106, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define IPU_FIELD_BPP IPU_CPMEM_WORD(0, 107, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define IPU_FIELD_DEC_SEL IPU_CPMEM_WORD(0, 110, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define IPU_FIELD_DIM IPU_CPMEM_WORD(0, 112, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define IPU_FIELD_BNDM IPU_CPMEM_WORD(0, 114, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define IPU_FIELD_BM IPU_CPMEM_WORD(0, 117, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define IPU_FIELD_ROT IPU_CPMEM_WORD(0, 119, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define IPU_FIELD_ROT_HF_VF IPU_CPMEM_WORD(0, 119, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define IPU_FIELD_HF IPU_CPMEM_WORD(0, 120, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define IPU_FIELD_VF IPU_CPMEM_WORD(0, 121, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define IPU_FIELD_THE IPU_CPMEM_WORD(0, 122, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define IPU_FIELD_CAP IPU_CPMEM_WORD(0, 123, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define IPU_FIELD_CAE IPU_CPMEM_WORD(0, 124, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define IPU_FIELD_FW IPU_CPMEM_WORD(0, 125, 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define IPU_FIELD_FH IPU_CPMEM_WORD(0, 138, 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define IPU_FIELD_EBA0 IPU_CPMEM_WORD(1, 0, 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define IPU_FIELD_EBA1 IPU_CPMEM_WORD(1, 29, 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define IPU_FIELD_ILO IPU_CPMEM_WORD(1, 58, 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define IPU_FIELD_NPB IPU_CPMEM_WORD(1, 78, 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define IPU_FIELD_PFS IPU_CPMEM_WORD(1, 85, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define IPU_FIELD_ALU IPU_CPMEM_WORD(1, 89, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define IPU_FIELD_ALBM IPU_CPMEM_WORD(1, 90, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define IPU_FIELD_ID IPU_CPMEM_WORD(1, 93, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define IPU_FIELD_TH IPU_CPMEM_WORD(1, 95, 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define IPU_FIELD_SL IPU_CPMEM_WORD(1, 102, 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define IPU_FIELD_WID0 IPU_CPMEM_WORD(1, 116, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define IPU_FIELD_WID1 IPU_CPMEM_WORD(1, 119, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define IPU_FIELD_WID2 IPU_CPMEM_WORD(1, 122, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define IPU_FIELD_WID3 IPU_CPMEM_WORD(1, 125, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define IPU_FIELD_OFS0 IPU_CPMEM_WORD(1, 128, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define IPU_FIELD_OFS1 IPU_CPMEM_WORD(1, 133, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define IPU_FIELD_OFS2 IPU_CPMEM_WORD(1, 138, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define IPU_FIELD_OFS3 IPU_CPMEM_WORD(1, 143, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define IPU_FIELD_SXYS IPU_CPMEM_WORD(1, 148, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define IPU_FIELD_CRE IPU_CPMEM_WORD(1, 149, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define IPU_FIELD_DEC_SEL2 IPU_CPMEM_WORD(1, 150, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static inline struct ipu_ch_param __iomem *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ipu_get_cpmem(struct ipuv3_channel *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct ipu_cpmem *cpmem = ch->ipu->cpmem_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return cpmem->base + ch->num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static void ipu_ch_param_write_field(struct ipuv3_channel *ch, u32 wbs, u32 v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct ipu_ch_param __iomem *base = ipu_get_cpmem(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u32 bit = (wbs >> 8) % 160;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) u32 size = wbs & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) u32 word = (wbs >> 8) / 160;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) u32 i = bit / 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) u32 ofs = bit % 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) u32 mask = (1 << size) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) pr_debug("%s %d %d %d\n", __func__, word, bit , size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) val = readl(&base->word[word].data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) val &= ~(mask << ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) val |= v << ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) writel(val, &base->word[word].data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if ((bit + size - 1) / 32 > i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) val = readl(&base->word[word].data[i + 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) val &= ~(mask >> (ofs ? (32 - ofs) : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) val |= v >> (ofs ? (32 - ofs) : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) writel(val, &base->word[word].data[i + 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static u32 ipu_ch_param_read_field(struct ipuv3_channel *ch, u32 wbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct ipu_ch_param __iomem *base = ipu_get_cpmem(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) u32 bit = (wbs >> 8) % 160;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) u32 size = wbs & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) u32 word = (wbs >> 8) / 160;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) u32 i = bit / 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) u32 ofs = bit % 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u32 mask = (1 << size) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) u32 val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) pr_debug("%s %d %d %d\n", __func__, word, bit , size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) val = (readl(&base->word[word].data[i]) >> ofs) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if ((bit + size - 1) / 32 > i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) tmp = readl(&base->word[word].data[i + 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) tmp &= mask >> (ofs ? (32 - ofs) : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) val |= tmp << (ofs ? (32 - ofs) : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * The V4L2 spec defines packed RGB formats in memory byte order, which from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * point of view of the IPU corresponds to little-endian words with the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * component in the least significant bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * The DRM pixel formats and IPU internal representation are ordered the other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * way around, with the first named component ordered at the most significant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * bits. Further, V4L2 formats are not well defined:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * https://linuxtv.org/downloads/v4l-dvb-apis/packed-rgb.html
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * We choose the interpretation which matches GStreamer behavior.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static int v4l2_pix_fmt_to_drm_fourcc(u32 pixelformat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) switch (pixelformat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) case V4L2_PIX_FMT_RGB565:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * Here we choose the 'corrected' interpretation of RGBP, a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * little-endian 16-bit word with the red component at the most
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * significant bits:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * g[2:0]b[4:0] r[4:0]g[5:3] <=> [16:0] R:G:B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return DRM_FORMAT_RGB565;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) case V4L2_PIX_FMT_BGR24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* B G R <=> [24:0] R:G:B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return DRM_FORMAT_RGB888;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) case V4L2_PIX_FMT_RGB24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* R G B <=> [24:0] B:G:R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return DRM_FORMAT_BGR888;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) case V4L2_PIX_FMT_BGR32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* B G R A <=> [32:0] A:B:G:R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return DRM_FORMAT_XRGB8888;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) case V4L2_PIX_FMT_RGB32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* R G B A <=> [32:0] A:B:G:R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return DRM_FORMAT_XBGR8888;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) case V4L2_PIX_FMT_ABGR32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /* B G R A <=> [32:0] A:R:G:B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return DRM_FORMAT_ARGB8888;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) case V4L2_PIX_FMT_XBGR32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* B G R X <=> [32:0] X:R:G:B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return DRM_FORMAT_XRGB8888;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) case V4L2_PIX_FMT_BGRA32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /* A B G R <=> [32:0] R:G:B:A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return DRM_FORMAT_RGBA8888;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) case V4L2_PIX_FMT_BGRX32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* X B G R <=> [32:0] R:G:B:X */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return DRM_FORMAT_RGBX8888;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) case V4L2_PIX_FMT_RGBA32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /* R G B A <=> [32:0] A:B:G:R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return DRM_FORMAT_ABGR8888;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) case V4L2_PIX_FMT_RGBX32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* R G B X <=> [32:0] X:B:G:R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return DRM_FORMAT_XBGR8888;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) case V4L2_PIX_FMT_ARGB32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* A R G B <=> [32:0] B:G:R:A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return DRM_FORMAT_BGRA8888;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) case V4L2_PIX_FMT_XRGB32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* X R G B <=> [32:0] B:G:R:X */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return DRM_FORMAT_BGRX8888;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) case V4L2_PIX_FMT_UYVY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return DRM_FORMAT_UYVY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) case V4L2_PIX_FMT_YUYV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return DRM_FORMAT_YUYV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) case V4L2_PIX_FMT_YUV420:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return DRM_FORMAT_YUV420;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) case V4L2_PIX_FMT_YUV422P:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return DRM_FORMAT_YUV422;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) case V4L2_PIX_FMT_YVU420:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return DRM_FORMAT_YVU420;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) case V4L2_PIX_FMT_NV12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return DRM_FORMAT_NV12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) case V4L2_PIX_FMT_NV16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return DRM_FORMAT_NV16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) void ipu_cpmem_zero(struct ipuv3_channel *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct ipu_ch_param __iomem *p = ipu_get_cpmem(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) void __iomem *base = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) for (i = 0; i < sizeof(*p) / sizeof(u32); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) writel(0, base + i * sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) EXPORT_SYMBOL_GPL(ipu_cpmem_zero);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) void ipu_cpmem_set_resolution(struct ipuv3_channel *ch, int xres, int yres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) ipu_ch_param_write_field(ch, IPU_FIELD_FW, xres - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) ipu_ch_param_write_field(ch, IPU_FIELD_FH, yres - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) EXPORT_SYMBOL_GPL(ipu_cpmem_set_resolution);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) void ipu_cpmem_skip_odd_chroma_rows(struct ipuv3_channel *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) ipu_ch_param_write_field(ch, IPU_FIELD_RDRW, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) EXPORT_SYMBOL_GPL(ipu_cpmem_skip_odd_chroma_rows);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) void ipu_cpmem_set_stride(struct ipuv3_channel *ch, int stride)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ipu_ch_param_write_field(ch, IPU_FIELD_SLY, stride - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) EXPORT_SYMBOL_GPL(ipu_cpmem_set_stride);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) void ipu_cpmem_set_high_priority(struct ipuv3_channel *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) struct ipu_soc *ipu = ch->ipu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (ipu->ipu_type == IPUV3EX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ipu_ch_param_write_field(ch, IPU_FIELD_ID, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) val = ipu_idmac_read(ipu, IDMAC_CHA_PRI(ch->num));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) val |= 1 << (ch->num % 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ipu_idmac_write(ipu, val, IDMAC_CHA_PRI(ch->num));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) EXPORT_SYMBOL_GPL(ipu_cpmem_set_high_priority);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) void ipu_cpmem_set_buffer(struct ipuv3_channel *ch, int bufnum, dma_addr_t buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) WARN_ON_ONCE(buf & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (bufnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ipu_ch_param_write_field(ch, IPU_FIELD_EBA1, buf >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ipu_ch_param_write_field(ch, IPU_FIELD_EBA0, buf >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) EXPORT_SYMBOL_GPL(ipu_cpmem_set_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) void ipu_cpmem_set_uv_offset(struct ipuv3_channel *ch, u32 u_off, u32 v_off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) WARN_ON_ONCE((u_off & 0x7) || (v_off & 0x7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_off / 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) ipu_ch_param_write_field(ch, IPU_FIELD_VBO, v_off / 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) EXPORT_SYMBOL_GPL(ipu_cpmem_set_uv_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) void ipu_cpmem_interlaced_scan(struct ipuv3_channel *ch, int stride,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) u32 pixelformat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) u32 ilo, sly, sluv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (stride < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) stride = -stride;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) ilo = 0x100000 - (stride / 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) ilo = stride / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) sly = (stride * 2) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) switch (pixelformat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) case V4L2_PIX_FMT_YUV420:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) case V4L2_PIX_FMT_YVU420:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) sluv = stride / 2 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) case V4L2_PIX_FMT_NV12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) sluv = stride - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) case V4L2_PIX_FMT_YUV422P:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) sluv = stride - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) case V4L2_PIX_FMT_NV16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) sluv = stride * 2 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) sluv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) ipu_ch_param_write_field(ch, IPU_FIELD_SO, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) ipu_ch_param_write_field(ch, IPU_FIELD_ILO, ilo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) ipu_ch_param_write_field(ch, IPU_FIELD_SLY, sly);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (sluv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, sluv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) EXPORT_SYMBOL_GPL(ipu_cpmem_interlaced_scan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) void ipu_cpmem_set_axi_id(struct ipuv3_channel *ch, u32 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) id &= 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ipu_ch_param_write_field(ch, IPU_FIELD_ID, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) EXPORT_SYMBOL_GPL(ipu_cpmem_set_axi_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) int ipu_cpmem_get_burstsize(struct ipuv3_channel *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return ipu_ch_param_read_field(ch, IPU_FIELD_NPB) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) EXPORT_SYMBOL_GPL(ipu_cpmem_get_burstsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) void ipu_cpmem_set_burstsize(struct ipuv3_channel *ch, int burstsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) ipu_ch_param_write_field(ch, IPU_FIELD_NPB, burstsize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) EXPORT_SYMBOL_GPL(ipu_cpmem_set_burstsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) void ipu_cpmem_set_block_mode(struct ipuv3_channel *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ipu_ch_param_write_field(ch, IPU_FIELD_BM, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) EXPORT_SYMBOL_GPL(ipu_cpmem_set_block_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) void ipu_cpmem_set_rotation(struct ipuv3_channel *ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) enum ipu_rotate_mode rot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) u32 temp_rot = bitrev8(rot) >> 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ipu_ch_param_write_field(ch, IPU_FIELD_ROT_HF_VF, temp_rot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) EXPORT_SYMBOL_GPL(ipu_cpmem_set_rotation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) int ipu_cpmem_set_format_rgb(struct ipuv3_channel *ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) const struct ipu_rgb *rgb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) int bpp = 0, npb = 0, ro, go, bo, to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) ro = rgb->bits_per_pixel - rgb->red.length - rgb->red.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) go = rgb->bits_per_pixel - rgb->green.length - rgb->green.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) bo = rgb->bits_per_pixel - rgb->blue.length - rgb->blue.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) to = rgb->bits_per_pixel - rgb->transp.length - rgb->transp.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) ipu_ch_param_write_field(ch, IPU_FIELD_WID0, rgb->red.length - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) ipu_ch_param_write_field(ch, IPU_FIELD_OFS0, ro);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) ipu_ch_param_write_field(ch, IPU_FIELD_WID1, rgb->green.length - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) ipu_ch_param_write_field(ch, IPU_FIELD_OFS1, go);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) ipu_ch_param_write_field(ch, IPU_FIELD_WID2, rgb->blue.length - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) ipu_ch_param_write_field(ch, IPU_FIELD_OFS2, bo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (rgb->transp.length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) ipu_ch_param_write_field(ch, IPU_FIELD_WID3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) rgb->transp.length - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) ipu_ch_param_write_field(ch, IPU_FIELD_OFS3, to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) ipu_ch_param_write_field(ch, IPU_FIELD_WID3, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ipu_ch_param_write_field(ch, IPU_FIELD_OFS3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) rgb->bits_per_pixel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) switch (rgb->bits_per_pixel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) bpp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) npb = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) case 24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) bpp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) npb = 19;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) bpp = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) npb = 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) bpp = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) npb = 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ipu_ch_param_write_field(ch, IPU_FIELD_BPP, bpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ipu_ch_param_write_field(ch, IPU_FIELD_NPB, npb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 7); /* rgb mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_rgb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) int ipu_cpmem_set_format_passthrough(struct ipuv3_channel *ch, int width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) int bpp = 0, npb = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) switch (width) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) bpp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) npb = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) case 24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) bpp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) npb = 19;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) bpp = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) npb = 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) bpp = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) npb = 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) ipu_ch_param_write_field(ch, IPU_FIELD_BPP, bpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ipu_ch_param_write_field(ch, IPU_FIELD_NPB, npb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 6); /* raw mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_passthrough);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) void ipu_cpmem_set_yuv_interleaved(struct ipuv3_channel *ch, u32 pixel_format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) switch (pixel_format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) case V4L2_PIX_FMT_UYVY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) ipu_ch_param_write_field(ch, IPU_FIELD_BPP, 3); /* bits/pixel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 0xA);/* pix fmt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);/* burst size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) case V4L2_PIX_FMT_YUYV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) ipu_ch_param_write_field(ch, IPU_FIELD_BPP, 3); /* bits/pixel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 0x8);/* pix fmt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);/* burst size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_interleaved);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) void ipu_cpmem_set_yuv_planar_full(struct ipuv3_channel *ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) unsigned int uv_stride,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) unsigned int u_offset, unsigned int v_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) WARN_ON_ONCE((u_offset & 0x7) || (v_offset & 0x7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, uv_stride - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_offset / 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) ipu_ch_param_write_field(ch, IPU_FIELD_VBO, v_offset / 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar_full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static const struct ipu_rgb def_xrgb_32 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) .red = { .offset = 16, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) .green = { .offset = 8, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) .blue = { .offset = 0, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) .transp = { .offset = 24, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) .bits_per_pixel = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) static const struct ipu_rgb def_xbgr_32 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) .red = { .offset = 0, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) .green = { .offset = 8, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) .blue = { .offset = 16, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) .transp = { .offset = 24, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) .bits_per_pixel = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static const struct ipu_rgb def_rgbx_32 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) .red = { .offset = 24, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) .green = { .offset = 16, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) .blue = { .offset = 8, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) .transp = { .offset = 0, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) .bits_per_pixel = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) static const struct ipu_rgb def_bgrx_32 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) .red = { .offset = 8, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) .green = { .offset = 16, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) .blue = { .offset = 24, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) .transp = { .offset = 0, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) .bits_per_pixel = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) static const struct ipu_rgb def_rgb_24 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) .red = { .offset = 16, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) .green = { .offset = 8, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) .blue = { .offset = 0, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) .transp = { .offset = 0, .length = 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) .bits_per_pixel = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) static const struct ipu_rgb def_bgr_24 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) .red = { .offset = 0, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) .green = { .offset = 8, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) .blue = { .offset = 16, .length = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) .transp = { .offset = 0, .length = 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) .bits_per_pixel = 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) static const struct ipu_rgb def_rgb_16 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) .red = { .offset = 11, .length = 5, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) .green = { .offset = 5, .length = 6, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) .blue = { .offset = 0, .length = 5, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) .transp = { .offset = 0, .length = 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) .bits_per_pixel = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) static const struct ipu_rgb def_bgr_16 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) .red = { .offset = 0, .length = 5, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .green = { .offset = 5, .length = 6, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) .blue = { .offset = 11, .length = 5, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) .transp = { .offset = 0, .length = 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .bits_per_pixel = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) static const struct ipu_rgb def_argb_16 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .red = { .offset = 10, .length = 5, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .green = { .offset = 5, .length = 5, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) .blue = { .offset = 0, .length = 5, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .transp = { .offset = 15, .length = 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) .bits_per_pixel = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static const struct ipu_rgb def_argb_16_4444 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) .red = { .offset = 8, .length = 4, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) .green = { .offset = 4, .length = 4, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) .blue = { .offset = 0, .length = 4, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) .transp = { .offset = 12, .length = 4, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) .bits_per_pixel = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) static const struct ipu_rgb def_abgr_16 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) .red = { .offset = 0, .length = 5, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) .green = { .offset = 5, .length = 5, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) .blue = { .offset = 10, .length = 5, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) .transp = { .offset = 15, .length = 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) .bits_per_pixel = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static const struct ipu_rgb def_rgba_16 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) .red = { .offset = 11, .length = 5, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) .green = { .offset = 6, .length = 5, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) .blue = { .offset = 1, .length = 5, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) .transp = { .offset = 0, .length = 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) .bits_per_pixel = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) static const struct ipu_rgb def_bgra_16 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) .red = { .offset = 1, .length = 5, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) .green = { .offset = 6, .length = 5, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) .blue = { .offset = 11, .length = 5, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) .transp = { .offset = 0, .length = 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) .bits_per_pixel = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) #define Y_OFFSET(pix, x, y) ((x) + pix->bytesperline * (y))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) #define U_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) (pix->bytesperline * ((y) / 2) / 2) + (x) / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) #define V_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) (pix->bytesperline * pix->height / 4) + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) (pix->bytesperline * ((y) / 2) / 2) + (x) / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) #define U2_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) (pix->bytesperline * (y) / 2) + (x) / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) #define V2_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) (pix->bytesperline * pix->height / 2) + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) (pix->bytesperline * (y) / 2) + (x) / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) #define UV_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) (pix->bytesperline * ((y) / 2)) + (x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) #define UV2_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) (pix->bytesperline * y) + (x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) #define NUM_ALPHA_CHANNELS 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) /* See Table 37-12. Alpha channels mapping. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static int ipu_channel_albm(int ch_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) switch (ch_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) case IPUV3_CHANNEL_G_MEM_IC_PRP_VF: return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) case IPUV3_CHANNEL_G_MEM_IC_PP: return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) case IPUV3_CHANNEL_MEM_FG_SYNC: return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) case IPUV3_CHANNEL_MEM_FG_ASYNC: return 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) case IPUV3_CHANNEL_MEM_BG_SYNC: return 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) case IPUV3_CHANNEL_MEM_BG_ASYNC: return 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) case IPUV3_CHANNEL_MEM_VDI_PLANE1_COMB: return 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) static void ipu_cpmem_set_separate_alpha(struct ipuv3_channel *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) struct ipu_soc *ipu = ch->ipu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) int albm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) albm = ipu_channel_albm(ch->num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (albm < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) ipu_ch_param_write_field(ch, IPU_FIELD_ALU, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) ipu_ch_param_write_field(ch, IPU_FIELD_ALBM, albm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) ipu_ch_param_write_field(ch, IPU_FIELD_CRE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) val = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) val |= BIT(ch->num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) ipu_idmac_write(ipu, val, IDMAC_SEP_ALPHA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) int ipu_cpmem_set_fmt(struct ipuv3_channel *ch, u32 drm_fourcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) switch (drm_fourcc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) case DRM_FORMAT_YUV420:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) case DRM_FORMAT_YVU420:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /* pix format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) /* burst size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) case DRM_FORMAT_YUV422:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) case DRM_FORMAT_YVU422:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) /* pix format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) /* burst size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) case DRM_FORMAT_YUV444:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) case DRM_FORMAT_YVU444:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) /* pix format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) /* burst size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) case DRM_FORMAT_NV12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /* pix format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /* burst size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) case DRM_FORMAT_NV16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) /* pix format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) /* burst size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) case DRM_FORMAT_UYVY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) /* bits/pixel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) ipu_ch_param_write_field(ch, IPU_FIELD_BPP, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) /* pix format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 0xA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) /* burst size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) case DRM_FORMAT_YUYV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /* bits/pixel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) ipu_ch_param_write_field(ch, IPU_FIELD_BPP, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) /* pix format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 0x8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) /* burst size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) case DRM_FORMAT_ABGR8888:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) case DRM_FORMAT_XBGR8888:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) ipu_cpmem_set_format_rgb(ch, &def_xbgr_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) case DRM_FORMAT_ARGB8888:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) case DRM_FORMAT_XRGB8888:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) ipu_cpmem_set_format_rgb(ch, &def_xrgb_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) case DRM_FORMAT_RGBA8888:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) case DRM_FORMAT_RGBX8888:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) case DRM_FORMAT_RGBX8888_A8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) ipu_cpmem_set_format_rgb(ch, &def_rgbx_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) case DRM_FORMAT_BGRA8888:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) case DRM_FORMAT_BGRX8888:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) case DRM_FORMAT_BGRX8888_A8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) ipu_cpmem_set_format_rgb(ch, &def_bgrx_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) case DRM_FORMAT_BGR888:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) case DRM_FORMAT_BGR888_A8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) ipu_cpmem_set_format_rgb(ch, &def_bgr_24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) case DRM_FORMAT_RGB888:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) case DRM_FORMAT_RGB888_A8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) ipu_cpmem_set_format_rgb(ch, &def_rgb_24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) case DRM_FORMAT_RGB565:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) case DRM_FORMAT_RGB565_A8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) ipu_cpmem_set_format_rgb(ch, &def_rgb_16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) case DRM_FORMAT_BGR565:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) case DRM_FORMAT_BGR565_A8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) ipu_cpmem_set_format_rgb(ch, &def_bgr_16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) case DRM_FORMAT_ARGB1555:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) ipu_cpmem_set_format_rgb(ch, &def_argb_16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) case DRM_FORMAT_ABGR1555:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) ipu_cpmem_set_format_rgb(ch, &def_abgr_16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) case DRM_FORMAT_RGBA5551:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) ipu_cpmem_set_format_rgb(ch, &def_rgba_16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) case DRM_FORMAT_BGRA5551:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) ipu_cpmem_set_format_rgb(ch, &def_bgra_16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) case DRM_FORMAT_ARGB4444:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) ipu_cpmem_set_format_rgb(ch, &def_argb_16_4444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) switch (drm_fourcc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) case DRM_FORMAT_RGB565_A8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) case DRM_FORMAT_BGR565_A8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) case DRM_FORMAT_RGB888_A8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) case DRM_FORMAT_BGR888_A8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) case DRM_FORMAT_RGBX8888_A8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) case DRM_FORMAT_BGRX8888_A8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) ipu_ch_param_write_field(ch, IPU_FIELD_WID3, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) ipu_cpmem_set_separate_alpha(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) EXPORT_SYMBOL_GPL(ipu_cpmem_set_fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) int ipu_cpmem_set_image(struct ipuv3_channel *ch, struct ipu_image *image)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) struct v4l2_pix_format *pix = &image->pix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) int offset, u_offset, v_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) pr_debug("%s: resolution: %dx%d stride: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) __func__, pix->width, pix->height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) pix->bytesperline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) ipu_cpmem_set_resolution(ch, image->rect.width, image->rect.height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) ipu_cpmem_set_stride(ch, pix->bytesperline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) ipu_cpmem_set_fmt(ch, v4l2_pix_fmt_to_drm_fourcc(pix->pixelformat));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) switch (pix->pixelformat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) case V4L2_PIX_FMT_YUV420:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) u_offset = image->u_offset ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) image->u_offset : U_OFFSET(pix, image->rect.left,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) image->rect.top) - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) v_offset = image->v_offset ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) image->v_offset : V_OFFSET(pix, image->rect.left,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) image->rect.top) - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) u_offset, v_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) case V4L2_PIX_FMT_YVU420:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) u_offset = image->u_offset ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) image->u_offset : V_OFFSET(pix, image->rect.left,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) image->rect.top) - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) v_offset = image->v_offset ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) image->v_offset : U_OFFSET(pix, image->rect.left,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) image->rect.top) - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) u_offset, v_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) case V4L2_PIX_FMT_YUV422P:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) u_offset = image->u_offset ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) image->u_offset : U2_OFFSET(pix, image->rect.left,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) image->rect.top) - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) v_offset = image->v_offset ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) image->v_offset : V2_OFFSET(pix, image->rect.left,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) image->rect.top) - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) u_offset, v_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) case V4L2_PIX_FMT_NV12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) u_offset = image->u_offset ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) image->u_offset : UV_OFFSET(pix, image->rect.left,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) image->rect.top) - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) v_offset = image->v_offset ? image->v_offset : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) u_offset, v_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) case V4L2_PIX_FMT_NV16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) u_offset = image->u_offset ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) image->u_offset : UV2_OFFSET(pix, image->rect.left,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) image->rect.top) - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) v_offset = image->v_offset ? image->v_offset : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) u_offset, v_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) case V4L2_PIX_FMT_UYVY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) case V4L2_PIX_FMT_YUYV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) case V4L2_PIX_FMT_RGB565:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) offset = image->rect.left * 2 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) image->rect.top * pix->bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) case V4L2_PIX_FMT_RGB32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) case V4L2_PIX_FMT_BGR32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) case V4L2_PIX_FMT_ABGR32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) case V4L2_PIX_FMT_XBGR32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) case V4L2_PIX_FMT_BGRA32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) case V4L2_PIX_FMT_BGRX32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) case V4L2_PIX_FMT_RGBA32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) case V4L2_PIX_FMT_RGBX32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) case V4L2_PIX_FMT_ARGB32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) case V4L2_PIX_FMT_XRGB32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) offset = image->rect.left * 4 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) image->rect.top * pix->bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) case V4L2_PIX_FMT_RGB24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) case V4L2_PIX_FMT_BGR24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) offset = image->rect.left * 3 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) image->rect.top * pix->bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) case V4L2_PIX_FMT_SBGGR8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) case V4L2_PIX_FMT_SGBRG8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) case V4L2_PIX_FMT_SGRBG8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) case V4L2_PIX_FMT_SRGGB8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) case V4L2_PIX_FMT_GREY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) offset = image->rect.left + image->rect.top * pix->bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) case V4L2_PIX_FMT_SBGGR16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) case V4L2_PIX_FMT_SGBRG16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) case V4L2_PIX_FMT_SGRBG16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) case V4L2_PIX_FMT_SRGGB16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) case V4L2_PIX_FMT_Y16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) offset = image->rect.left * 2 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) image->rect.top * pix->bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) /* This should not happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) ipu_cpmem_set_buffer(ch, 0, image->phys0 + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) ipu_cpmem_set_buffer(ch, 1, image->phys1 + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) EXPORT_SYMBOL_GPL(ipu_cpmem_set_image);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) void ipu_cpmem_dump(struct ipuv3_channel *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) struct ipu_ch_param __iomem *p = ipu_get_cpmem(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) struct ipu_soc *ipu = ch->ipu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) int chno = ch->num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) dev_dbg(ipu->dev, "ch %d word 0 - %08X %08X %08X %08X %08X\n", chno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) readl(&p->word[0].data[0]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) readl(&p->word[0].data[1]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) readl(&p->word[0].data[2]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) readl(&p->word[0].data[3]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) readl(&p->word[0].data[4]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) dev_dbg(ipu->dev, "ch %d word 1 - %08X %08X %08X %08X %08X\n", chno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) readl(&p->word[1].data[0]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) readl(&p->word[1].data[1]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) readl(&p->word[1].data[2]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) readl(&p->word[1].data[3]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) readl(&p->word[1].data[4]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) dev_dbg(ipu->dev, "PFS 0x%x, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) ipu_ch_param_read_field(ch, IPU_FIELD_PFS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) dev_dbg(ipu->dev, "BPP 0x%x, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) ipu_ch_param_read_field(ch, IPU_FIELD_BPP));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) dev_dbg(ipu->dev, "NPB 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) ipu_ch_param_read_field(ch, IPU_FIELD_NPB));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) dev_dbg(ipu->dev, "FW %d, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) ipu_ch_param_read_field(ch, IPU_FIELD_FW));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) dev_dbg(ipu->dev, "FH %d, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) ipu_ch_param_read_field(ch, IPU_FIELD_FH));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) dev_dbg(ipu->dev, "EBA0 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) ipu_ch_param_read_field(ch, IPU_FIELD_EBA0) << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) dev_dbg(ipu->dev, "EBA1 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) ipu_ch_param_read_field(ch, IPU_FIELD_EBA1) << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) dev_dbg(ipu->dev, "Stride %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) ipu_ch_param_read_field(ch, IPU_FIELD_SL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) dev_dbg(ipu->dev, "scan_order %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) ipu_ch_param_read_field(ch, IPU_FIELD_SO));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) dev_dbg(ipu->dev, "uv_stride %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) ipu_ch_param_read_field(ch, IPU_FIELD_SLUV));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) dev_dbg(ipu->dev, "u_offset 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) ipu_ch_param_read_field(ch, IPU_FIELD_UBO) << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) dev_dbg(ipu->dev, "v_offset 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) ipu_ch_param_read_field(ch, IPU_FIELD_VBO) << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) dev_dbg(ipu->dev, "Width0 %d+1, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) ipu_ch_param_read_field(ch, IPU_FIELD_WID0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) dev_dbg(ipu->dev, "Width1 %d+1, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) ipu_ch_param_read_field(ch, IPU_FIELD_WID1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) dev_dbg(ipu->dev, "Width2 %d+1, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) ipu_ch_param_read_field(ch, IPU_FIELD_WID2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) dev_dbg(ipu->dev, "Width3 %d+1, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) ipu_ch_param_read_field(ch, IPU_FIELD_WID3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) dev_dbg(ipu->dev, "Offset0 %d, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) ipu_ch_param_read_field(ch, IPU_FIELD_OFS0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) dev_dbg(ipu->dev, "Offset1 %d, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) ipu_ch_param_read_field(ch, IPU_FIELD_OFS1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) dev_dbg(ipu->dev, "Offset2 %d, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) ipu_ch_param_read_field(ch, IPU_FIELD_OFS2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) dev_dbg(ipu->dev, "Offset3 %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) ipu_ch_param_read_field(ch, IPU_FIELD_OFS3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) EXPORT_SYMBOL_GPL(ipu_cpmem_dump);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) int ipu_cpmem_init(struct ipu_soc *ipu, struct device *dev, unsigned long base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) struct ipu_cpmem *cpmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) cpmem = devm_kzalloc(dev, sizeof(*cpmem), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) if (!cpmem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) ipu->cpmem_priv = cpmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) spin_lock_init(&cpmem->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) cpmem->base = devm_ioremap(dev, base, SZ_128K);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (!cpmem->base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) dev_dbg(dev, "CPMEM base: 0x%08lx remapped to %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) base, cpmem->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) cpmem->ipu = ipu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) void ipu_cpmem_exit(struct ipu_soc *ipu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }