brintos

brintos / linux-shallow public Read only

0
0
Text · 5.9 KiB · c958614 Raw
207 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * camss-csid-4-1.c4 *5 * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module6 *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		0x021#define CAMSS_CSID_CORE_CTRL_0		0x00422#define CAMSS_CSID_CORE_CTRL_1		0x00823#define CAMSS_CSID_RST_CMD		0x00c24#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	429#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	0x06036#define CAMSS_CSID_IRQ_MASK		0x06437#define CAMSS_CSID_IRQ_STATUS		0x06838#define CAMSS_CSID_TG_CTRL		0x0a039#define CAMSS_CSID_TG_CTRL_DISABLE	0xa0643640#define CAMSS_CSID_TG_CTRL_ENABLE	0xa0643741#define CAMSS_CSID_TG_VC_CFG		0x0a442#define CAMSS_CSID_TG_VC_CFG_H_BLANKING		0x3ff43#define CAMSS_CSID_TG_VC_CFG_V_BLANKING		0x7f44#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 void csid_configure_stream(struct csid_device *csid, u8 enable)49{50	struct csid_testgen_config *tg = &csid->testgen;51	u32 val;52 53	if (enable) {54		struct v4l2_mbus_framefmt *input_format;55		const struct csid_format_info *format;56		u8 vc = 0; /* Virtual Channel 0 */57		u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */58		u8 dt_shift;59 60		if (tg->enabled) {61			/* Config Test Generator */62			u32 num_lines, num_bytes_per_line;63 64			input_format = &csid->fmt[MSM_CSID_PAD_SRC];65			format = csid_get_fmt_entry(csid->res->formats->formats,66						    csid->res->formats->nformats,67						    input_format->code);68			num_bytes_per_line = input_format->width * format->bpp * format->spp / 8;69			num_lines = input_format->height;70 71			/* 31:24 V blank, 23:13 H blank, 3:2 num of active DT */72			/* 1:0 VC */73			val = ((CAMSS_CSID_TG_VC_CFG_V_BLANKING & 0xff) << 24) |74				  ((CAMSS_CSID_TG_VC_CFG_H_BLANKING & 0x7ff) << 13);75			writel_relaxed(val, csid->base + CAMSS_CSID_TG_VC_CFG);76 77			/* 28:16 bytes per lines, 12:0 num of lines */78			val = ((num_bytes_per_line & 0x1fff) << 16) |79				  (num_lines & 0x1fff);80			writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_0(0));81 82			/* 5:0 data type */83			val = format->data_type;84			writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_1(0));85 86			/* 2:0 output test pattern */87			val = tg->mode - 1;88			writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_2(0));89		} else {90			struct csid_phy_config *phy = &csid->phy;91 92			input_format = &csid->fmt[MSM_CSID_PAD_SINK];93			format = csid_get_fmt_entry(csid->res->formats->formats,94						    csid->res->formats->nformats,95						    input_format->code);96 97			val = phy->lane_cnt - 1;98			val |= phy->lane_assign << 4;99 100			writel_relaxed(val, csid->base + CAMSS_CSID_CORE_CTRL_0);101 102			val = phy->csiphy_id << 17;103			val |= 0x9;104 105			writel_relaxed(val, csid->base + CAMSS_CSID_CORE_CTRL_1);106		}107 108		/* Config LUT */109 110		dt_shift = (cid % 4) * 8;111		val = readl_relaxed(csid->base + CAMSS_CSID_CID_LUT_VC_n(vc));112		val &= ~(0xff << dt_shift);113		val |= format->data_type << dt_shift;114		writel_relaxed(val, csid->base + CAMSS_CSID_CID_LUT_VC_n(vc));115 116		val = CAMSS_CSID_CID_n_CFG_ISPIF_EN;117		val |= CAMSS_CSID_CID_n_CFG_RDI_EN;118		val |= format->decode_format << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT;119		val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP;120		writel_relaxed(val, csid->base + CAMSS_CSID_CID_n_CFG(cid));121 122		if (tg->enabled) {123			val = CAMSS_CSID_TG_CTRL_ENABLE;124			writel_relaxed(val, csid->base + CAMSS_CSID_TG_CTRL);125		}126	} else {127		if (tg->enabled) {128			val = CAMSS_CSID_TG_CTRL_DISABLE;129			writel_relaxed(val, csid->base + CAMSS_CSID_TG_CTRL);130		}131	}132}133 134static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val)135{136	if (val > 0 && val <= csid->testgen.nmodes)137		csid->testgen.mode = val;138 139	return 0;140}141 142static u32 csid_hw_version(struct csid_device *csid)143{144	u32 hw_version = readl_relaxed(csid->base + CAMSS_CSID_HW_VERSION);145 146	dev_dbg(csid->camss->dev, "CSID HW Version = 0x%08x\n", hw_version);147 148	return hw_version;149}150 151static irqreturn_t csid_isr(int irq, void *dev)152{153	struct csid_device *csid = dev;154	u32 value;155 156	value = readl_relaxed(csid->base + CAMSS_CSID_IRQ_STATUS);157	writel_relaxed(value, csid->base + CAMSS_CSID_IRQ_CLEAR_CMD);158 159	if ((value >> 11) & 0x1)160		complete(&csid->reset_complete);161 162	return IRQ_HANDLED;163}164 165static int csid_reset(struct csid_device *csid)166{167	unsigned long time;168 169	reinit_completion(&csid->reset_complete);170 171	writel_relaxed(0x7fff, csid->base + CAMSS_CSID_RST_CMD);172 173	time = wait_for_completion_timeout(&csid->reset_complete,174					   msecs_to_jiffies(CSID_RESET_TIMEOUT_MS));175	if (!time) {176		dev_err(csid->camss->dev, "CSID reset timeout\n");177		return -EIO;178	}179 180	return 0;181}182 183static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code,184			     unsigned int match_format_idx, u32 match_code)185{186	if (match_format_idx > 0)187		return 0;188 189	return sink_code;190}191 192static void csid_subdev_init(struct csid_device *csid)193{194	csid->testgen.modes = csid_testgen_modes;195	csid->testgen.nmodes = CSID_PAYLOAD_MODE_NUM_SUPPORTED_GEN1;196}197 198const struct csid_hw_ops csid_ops_4_1 = {199	.configure_stream = csid_configure_stream,200	.configure_testgen_pattern = csid_configure_testgen_pattern,201	.hw_version = csid_hw_version,202	.isr = csid_isr,203	.reset = csid_reset,204	.src_pad_code = csid_src_pad_code,205	.subdev_init = csid_subdev_init,206};207