cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

camss-csid-4-1.c (7910B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * camss-csid-4-1.c
      4 *
      5 * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module
      6 *
      7 * Copyright (C) 2020 Linaro Ltd.
      8 */
      9
     10#include <linux/completion.h>
     11#include <linux/interrupt.h>
     12#include <linux/io.h>
     13#include <linux/kernel.h>
     14#include <linux/of.h>
     15
     16#include "camss-csid.h"
     17#include "camss-csid-gen1.h"
     18#include "camss.h"
     19
     20#define CAMSS_CSID_HW_VERSION		0x0
     21#define CAMSS_CSID_CORE_CTRL_0		0x004
     22#define CAMSS_CSID_CORE_CTRL_1		0x008
     23#define CAMSS_CSID_RST_CMD		0x00c
     24#define CAMSS_CSID_CID_LUT_VC_n(n)	(0x010 + 0x4 * (n))
     25#define CAMSS_CSID_CID_n_CFG(n)		(0x020 + 0x4 * (n))
     26#define CAMSS_CSID_CID_n_CFG_ISPIF_EN	BIT(0)
     27#define CAMSS_CSID_CID_n_CFG_RDI_EN	BIT(1)
     28#define CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT	4
     29#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_8		(PLAIN_FORMAT_PLAIN8 << 8)
     30#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16		(PLAIN_FORMAT_PLAIN16 << 8)
     31#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB	(0 << 9)
     32#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_MSB	(1 << 9)
     33#define CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP		(0 << 10)
     34#define CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING	(1 << 10)
     35#define CAMSS_CSID_IRQ_CLEAR_CMD	0x060
     36#define CAMSS_CSID_IRQ_MASK		0x064
     37#define CAMSS_CSID_IRQ_STATUS		0x068
     38#define CAMSS_CSID_TG_CTRL		0x0a0
     39#define CAMSS_CSID_TG_CTRL_DISABLE	0xa06436
     40#define CAMSS_CSID_TG_CTRL_ENABLE	0xa06437
     41#define CAMSS_CSID_TG_VC_CFG		0x0a4
     42#define CAMSS_CSID_TG_VC_CFG_H_BLANKING		0x3ff
     43#define CAMSS_CSID_TG_VC_CFG_V_BLANKING		0x7f
     44#define CAMSS_CSID_TG_DT_n_CGG_0(n)	(0x0ac + 0xc * (n))
     45#define CAMSS_CSID_TG_DT_n_CGG_1(n)	(0x0b0 + 0xc * (n))
     46#define CAMSS_CSID_TG_DT_n_CGG_2(n)	(0x0b4 + 0xc * (n))
     47
     48static const struct csid_format csid_formats[] = {
     49	{
     50		MEDIA_BUS_FMT_UYVY8_2X8,
     51		DATA_TYPE_YUV422_8BIT,
     52		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
     53		8,
     54		2,
     55	},
     56	{
     57		MEDIA_BUS_FMT_VYUY8_2X8,
     58		DATA_TYPE_YUV422_8BIT,
     59		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
     60		8,
     61		2,
     62	},
     63	{
     64		MEDIA_BUS_FMT_YUYV8_2X8,
     65		DATA_TYPE_YUV422_8BIT,
     66		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
     67		8,
     68		2,
     69	},
     70	{
     71		MEDIA_BUS_FMT_YVYU8_2X8,
     72		DATA_TYPE_YUV422_8BIT,
     73		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
     74		8,
     75		2,
     76	},
     77	{
     78		MEDIA_BUS_FMT_SBGGR8_1X8,
     79		DATA_TYPE_RAW_8BIT,
     80		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
     81		8,
     82		1,
     83	},
     84	{
     85		MEDIA_BUS_FMT_SGBRG8_1X8,
     86		DATA_TYPE_RAW_8BIT,
     87		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
     88		8,
     89		1,
     90	},
     91	{
     92		MEDIA_BUS_FMT_SGRBG8_1X8,
     93		DATA_TYPE_RAW_8BIT,
     94		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
     95		8,
     96		1,
     97	},
     98	{
     99		MEDIA_BUS_FMT_SRGGB8_1X8,
    100		DATA_TYPE_RAW_8BIT,
    101		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
    102		8,
    103		1,
    104	},
    105	{
    106		MEDIA_BUS_FMT_SBGGR10_1X10,
    107		DATA_TYPE_RAW_10BIT,
    108		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
    109		10,
    110		1,
    111	},
    112	{
    113		MEDIA_BUS_FMT_SGBRG10_1X10,
    114		DATA_TYPE_RAW_10BIT,
    115		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
    116		10,
    117		1,
    118	},
    119	{
    120		MEDIA_BUS_FMT_SGRBG10_1X10,
    121		DATA_TYPE_RAW_10BIT,
    122		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
    123		10,
    124		1,
    125	},
    126	{
    127		MEDIA_BUS_FMT_SRGGB10_1X10,
    128		DATA_TYPE_RAW_10BIT,
    129		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
    130		10,
    131		1,
    132	},
    133	{
    134		MEDIA_BUS_FMT_SBGGR12_1X12,
    135		DATA_TYPE_RAW_12BIT,
    136		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
    137		12,
    138		1,
    139	},
    140	{
    141		MEDIA_BUS_FMT_SGBRG12_1X12,
    142		DATA_TYPE_RAW_12BIT,
    143		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
    144		12,
    145		1,
    146	},
    147	{
    148		MEDIA_BUS_FMT_SGRBG12_1X12,
    149		DATA_TYPE_RAW_12BIT,
    150		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
    151		12,
    152		1,
    153	},
    154	{
    155		MEDIA_BUS_FMT_SRGGB12_1X12,
    156		DATA_TYPE_RAW_12BIT,
    157		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
    158		12,
    159		1,
    160	},
    161	{
    162		MEDIA_BUS_FMT_Y10_1X10,
    163		DATA_TYPE_RAW_10BIT,
    164		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
    165		10,
    166		1,
    167	},
    168};
    169
    170static void csid_configure_stream(struct csid_device *csid, u8 enable)
    171{
    172	struct csid_testgen_config *tg = &csid->testgen;
    173	u32 val;
    174
    175	if (enable) {
    176		struct v4l2_mbus_framefmt *input_format;
    177		const struct csid_format *format;
    178		u8 vc = 0; /* Virtual Channel 0 */
    179		u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */
    180		u8 dt_shift;
    181
    182		if (tg->enabled) {
    183			/* Config Test Generator */
    184			u32 num_lines, num_bytes_per_line;
    185
    186			input_format = &csid->fmt[MSM_CSID_PAD_SRC];
    187			format = csid_get_fmt_entry(csid->formats, csid->nformats,
    188						    input_format->code);
    189			num_bytes_per_line = input_format->width * format->bpp * format->spp / 8;
    190			num_lines = input_format->height;
    191
    192			/* 31:24 V blank, 23:13 H blank, 3:2 num of active DT */
    193			/* 1:0 VC */
    194			val = ((CAMSS_CSID_TG_VC_CFG_V_BLANKING & 0xff) << 24) |
    195				  ((CAMSS_CSID_TG_VC_CFG_H_BLANKING & 0x7ff) << 13);
    196			writel_relaxed(val, csid->base + CAMSS_CSID_TG_VC_CFG);
    197
    198			/* 28:16 bytes per lines, 12:0 num of lines */
    199			val = ((num_bytes_per_line & 0x1fff) << 16) |
    200				  (num_lines & 0x1fff);
    201			writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_0(0));
    202
    203			/* 5:0 data type */
    204			val = format->data_type;
    205			writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_1(0));
    206
    207			/* 2:0 output test pattern */
    208			val = tg->mode - 1;
    209			writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_2(0));
    210		} else {
    211			struct csid_phy_config *phy = &csid->phy;
    212
    213			input_format = &csid->fmt[MSM_CSID_PAD_SINK];
    214			format = csid_get_fmt_entry(csid->formats, csid->nformats,
    215						    input_format->code);
    216
    217			val = phy->lane_cnt - 1;
    218			val |= phy->lane_assign << 4;
    219
    220			writel_relaxed(val, csid->base + CAMSS_CSID_CORE_CTRL_0);
    221
    222			val = phy->csiphy_id << 17;
    223			val |= 0x9;
    224
    225			writel_relaxed(val, csid->base + CAMSS_CSID_CORE_CTRL_1);
    226		}
    227
    228		/* Config LUT */
    229
    230		dt_shift = (cid % 4) * 8;
    231		val = readl_relaxed(csid->base + CAMSS_CSID_CID_LUT_VC_n(vc));
    232		val &= ~(0xff << dt_shift);
    233		val |= format->data_type << dt_shift;
    234		writel_relaxed(val, csid->base + CAMSS_CSID_CID_LUT_VC_n(vc));
    235
    236		val = CAMSS_CSID_CID_n_CFG_ISPIF_EN;
    237		val |= CAMSS_CSID_CID_n_CFG_RDI_EN;
    238		val |= format->decode_format << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT;
    239		val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP;
    240		writel_relaxed(val, csid->base + CAMSS_CSID_CID_n_CFG(cid));
    241
    242		if (tg->enabled) {
    243			val = CAMSS_CSID_TG_CTRL_ENABLE;
    244			writel_relaxed(val, csid->base + CAMSS_CSID_TG_CTRL);
    245		}
    246	} else {
    247		if (tg->enabled) {
    248			val = CAMSS_CSID_TG_CTRL_DISABLE;
    249			writel_relaxed(val, csid->base + CAMSS_CSID_TG_CTRL);
    250		}
    251	}
    252}
    253
    254static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val)
    255{
    256	if (val > 0 && val <= csid->testgen.nmodes)
    257		csid->testgen.mode = val;
    258
    259	return 0;
    260}
    261
    262static u32 csid_hw_version(struct csid_device *csid)
    263{
    264	u32 hw_version = readl_relaxed(csid->base + CAMSS_CSID_HW_VERSION);
    265
    266	dev_dbg(csid->camss->dev, "CSID HW Version = 0x%08x\n", hw_version);
    267
    268	return hw_version;
    269}
    270
    271static irqreturn_t csid_isr(int irq, void *dev)
    272{
    273	struct csid_device *csid = dev;
    274	u32 value;
    275
    276	value = readl_relaxed(csid->base + CAMSS_CSID_IRQ_STATUS);
    277	writel_relaxed(value, csid->base + CAMSS_CSID_IRQ_CLEAR_CMD);
    278
    279	if ((value >> 11) & 0x1)
    280		complete(&csid->reset_complete);
    281
    282	return IRQ_HANDLED;
    283}
    284
    285static int csid_reset(struct csid_device *csid)
    286{
    287	unsigned long time;
    288
    289	reinit_completion(&csid->reset_complete);
    290
    291	writel_relaxed(0x7fff, csid->base + CAMSS_CSID_RST_CMD);
    292
    293	time = wait_for_completion_timeout(&csid->reset_complete,
    294					   msecs_to_jiffies(CSID_RESET_TIMEOUT_MS));
    295	if (!time) {
    296		dev_err(csid->camss->dev, "CSID reset timeout\n");
    297		return -EIO;
    298	}
    299
    300	return 0;
    301}
    302
    303static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code,
    304			     unsigned int match_format_idx, u32 match_code)
    305{
    306	if (match_format_idx > 0)
    307		return 0;
    308
    309	return sink_code;
    310}
    311
    312static void csid_subdev_init(struct csid_device *csid)
    313{
    314	csid->formats = csid_formats;
    315	csid->nformats = ARRAY_SIZE(csid_formats);
    316	csid->testgen.modes = csid_testgen_modes;
    317	csid->testgen.nmodes = CSID_PAYLOAD_MODE_NUM_SUPPORTED_GEN1;
    318}
    319
    320const struct csid_hw_ops csid_ops_4_1 = {
    321	.configure_stream = csid_configure_stream,
    322	.configure_testgen_pattern = csid_configure_testgen_pattern,
    323	.hw_version = csid_hw_version,
    324	.isr = csid_isr,
    325	.reset = csid_reset,
    326	.src_pad_code = csid_src_pad_code,
    327	.subdev_init = csid_subdev_init,
    328};