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-7.c (9598B)


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