File Index
Files and directories
Sign in
FILE

ipu6-isys.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/pci/intel/ipu6/ipu6-isys.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2013--2024 Intel Corporation
   4 */
   5
   6#include <linux/auxiliary_bus.h>
   7#include <linux/bitfield.h>
   8#include <linux/bits.h>
   9#include <linux/completion.h>
  10#include <linux/container_of.h>
  11#include <linux/delay.h>
  12#include <linux/device.h>
  13#include <linux/dma-mapping.h>
  14#include <linux/err.h>
  15#include <linux/firmware.h>
  16#include <linux/io.h>
  17#include <linux/irqreturn.h>
  18#include <linux/list.h>
  19#include <linux/module.h>
  20#include <linux/mutex.h>
  21#include <linux/pci.h>
  22#include <linux/pm_runtime.h>
  23#include <linux/pm_qos.h>
  24#include <linux/slab.h>
  25#include <linux/spinlock.h>
  26#include <linux/string.h>
  27
  28#include <media/ipu-bridge.h>
  29#include <media/media-device.h>
  30#include <media/media-entity.h>
  31#include <media/v4l2-async.h>
  32#include <media/v4l2-device.h>
  33#include <media/v4l2-fwnode.h>
  34
  35#include "ipu6-bus.h"
  36#include "ipu6-cpd.h"
  37#include "ipu6-dma.h"
  38#include "ipu6-isys.h"
  39#include "ipu6-isys-csi2.h"
  40#include "ipu6-mmu.h"
  41#include "ipu6-platform-buttress-regs.h"
  42#include "ipu6-platform-isys-csi2-reg.h"
  43#include "ipu6-platform-regs.h"
  44
  45#define IPU6_BUTTRESS_FABIC_CONTROL		0x68
  46#define GDA_ENABLE_IWAKE_INDEX			2
  47#define GDA_IWAKE_THRESHOLD_INDEX		1
  48#define GDA_IRQ_CRITICAL_THRESHOLD_INDEX	0
  49#define GDA_MEMOPEN_THRESHOLD_INDEX		3
  50#define DEFAULT_DID_RATIO			90
  51#define DEFAULT_IWAKE_THRESHOLD			0x42
  52#define DEFAULT_MEM_OPEN_TIME			10
  53#define ONE_THOUSAND_MICROSECOND		1000
  54/* One page is 2KB, 8 x 16 x 16 = 2048B = 2KB */
  55#define ISF_DMA_TOP_GDA_PROFERTY_PAGE_SIZE	0x800
  56
  57/* LTR & DID value are 10 bit at most */
  58#define LTR_DID_VAL_MAX				1023
  59#define LTR_DEFAULT_VALUE			0x70503c19
  60#define FILL_TIME_DEFAULT_VALUE			0xfff0783c
  61#define LTR_DID_PKGC_2R				20
  62#define LTR_SCALE_DEFAULT			5
  63#define LTR_SCALE_1024NS			2
  64#define DID_SCALE_1US				2
  65#define DID_SCALE_32US				3
  66#define REG_PKGC_PMON_CFG			0xb00
  67
  68#define VAL_PKGC_PMON_CFG_RESET			0x38
  69#define VAL_PKGC_PMON_CFG_START			0x7
  70
  71#define IS_PIXEL_BUFFER_PAGES			0x80
  72/*
  73 * when iwake mode is disabled, the critical threshold is statically set
  74 * to 75% of the IS pixel buffer, criticalThreshold = (128 * 3) / 4
  75 */
  76#define CRITICAL_THRESHOLD_IWAKE_DISABLE	(IS_PIXEL_BUFFER_PAGES * 3 / 4)
  77
  78union fabric_ctrl {
  79	struct {
  80		u16 ltr_val   : 10;
  81		u16 ltr_scale : 3;
  82		u16 reserved  : 3;
  83		u16 did_val   : 10;
  84		u16 did_scale : 3;
  85		u16 reserved2 : 1;
  86		u16 keep_power_in_D0   : 1;
  87		u16 keep_power_override : 1;
  88	} bits;
  89	u32 value;
  90};
  91
  92enum ltr_did_type {
  93	LTR_IWAKE_ON,
  94	LTR_IWAKE_OFF,
  95	LTR_ISYS_ON,
  96	LTR_ISYS_OFF,
  97	LTR_ENHANNCE_IWAKE,
  98	LTR_TYPE_MAX
  99};
 100
 101#define ISYS_PM_QOS_VALUE	300
 102
 103static int isys_isr_one(struct ipu6_bus_device *adev);
 104
 105static int
 106isys_complete_ext_device_registration(struct ipu6_isys *isys,
 107				      struct v4l2_subdev *sd,
 108				      struct ipu6_isys_csi2_config *csi2)
 109{
 110	struct device *dev = &isys->adev->auxdev.dev;
 111	unsigned int i;
 112	int ret;
 113
 114	for (i = 0; i < sd->entity.num_pads; i++) {
 115		if (sd->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE)
 116			break;
 117	}
 118
 119	if (i == sd->entity.num_pads) {
 120		dev_warn(dev, "no src pad in external entity\n");
 121		ret = -ENOENT;
 122		goto unregister_subdev;
 123	}
 124
 125	ret = media_create_pad_link(&sd->entity, i,
 126				    &isys->csi2[csi2->port].asd.sd.entity,
 127				    0, MEDIA_LNK_FL_ENABLED |
 128				       MEDIA_LNK_FL_IMMUTABLE);
 129	if (ret) {
 130		dev_warn(dev, "can't create link\n");
 131		goto unregister_subdev;
 132	}
 133
 134	isys->csi2[csi2->port].nlanes = csi2->nlanes;
 135
 136	return 0;
 137
 138unregister_subdev:
 139	v4l2_device_unregister_subdev(sd);
 140
 141	return ret;
 142}
 143
 144static void isys_stream_init(struct ipu6_isys *isys)
 145{
 146	u32 i;
 147
 148	for (i = 0; i < IPU6_ISYS_MAX_STREAMS; i++) {
 149		mutex_init(&isys->streams[i].mutex);
 150		init_completion(&isys->streams[i].stream_open_completion);
 151		init_completion(&isys->streams[i].stream_close_completion);
 152		init_completion(&isys->streams[i].stream_start_completion);
 153		init_completion(&isys->streams[i].stream_stop_completion);
 154		INIT_LIST_HEAD(&isys->streams[i].queues);
 155		isys->streams[i].isys = isys;
 156		isys->streams[i].stream_handle = i;
 157		isys->streams[i].vc = INVALID_VC_ID;
 158	}
 159}
 160
 161static void isys_csi2_unregister_subdevices(struct ipu6_isys *isys)
 162{
 163	const struct ipu6_isys_internal_csi2_pdata *csi2 =
 164		&isys->pdata->ipdata->csi2;
 165	unsigned int i;
 166
 167	for (i = 0; i < csi2->nports; i++)
 168		ipu6_isys_csi2_cleanup(&isys->csi2[i]);
 169}
 170
 171static int isys_csi2_register_subdevices(struct ipu6_isys *isys)
 172{
 173	const struct ipu6_isys_internal_csi2_pdata *csi2_pdata =
 174		&isys->pdata->ipdata->csi2;
 175	unsigned int i;
 176	int ret;
 177
 178	for (i = 0; i < csi2_pdata->nports; i++) {
 179		ret = ipu6_isys_csi2_init(&isys->csi2[i], isys,
 180					  isys->pdata->base +
 181					  CSI_REG_PORT_BASE(i), i);
 182		if (ret)
 183			goto fail;
 184
 185		isys->isr_csi2_bits |= IPU6_ISYS_UNISPART_IRQ_CSI2(i);
 186	}
 187
 188	return 0;
 189
 190fail:
 191	while (i--)
 192		ipu6_isys_csi2_cleanup(&isys->csi2[i]);
 193
 194	return ret;
 195}
 196
 197static int isys_csi2_create_media_links(struct ipu6_isys *isys)
 198{
 199	const struct ipu6_isys_internal_csi2_pdata *csi2_pdata =
 200		&isys->pdata->ipdata->csi2;
 201	struct device *dev = &isys->adev->auxdev.dev;
 202	unsigned int i, j;
 203	int ret;
 204
 205	for (i = 0; i < csi2_pdata->nports; i++) {
 206		struct media_entity *sd = &isys->csi2[i].asd.sd.entity;
 207
 208		for (j = 0; j < NR_OF_CSI2_SRC_PADS; j++) {
 209			struct ipu6_isys_video *av = &isys->csi2[i].av[j];
 210
 211			ret = media_create_pad_link(sd, CSI2_PAD_SRC + j,
 212						    &av->vdev.entity, 0, 0);
 213			if (ret) {
 214				dev_err(dev, "CSI2 can't create link\n");
 215				return ret;
 216			}
 217
 218			av->csi2 = &isys->csi2[i];
 219		}
 220	}
 221
 222	return 0;
 223}
 224
 225static void isys_unregister_video_devices(struct ipu6_isys *isys)
 226{
 227	const struct ipu6_isys_internal_csi2_pdata *csi2_pdata =
 228		&isys->pdata->ipdata->csi2;
 229	unsigned int i, j;
 230
 231	for (i = 0; i < csi2_pdata->nports; i++)
 232		for (j = 0; j < NR_OF_CSI2_SRC_PADS; j++)
 233			ipu6_isys_video_cleanup(&isys->csi2[i].av[j]);
 234}
 235
 236static int isys_register_video_devices(struct ipu6_isys *isys)
 237{
 238	const struct ipu6_isys_internal_csi2_pdata *csi2_pdata =
 239		&isys->pdata->ipdata->csi2;
 240	unsigned int i, j;
 241	int ret;
 242
 243	for (i = 0; i < csi2_pdata->nports; i++) {
 244		for (j = 0; j < NR_OF_CSI2_SRC_PADS; j++) {
 245			struct ipu6_isys_video *av = &isys->csi2[i].av[j];
 246
 247			snprintf(av->vdev.name, sizeof(av->vdev.name),
 248				 IPU6_ISYS_ENTITY_PREFIX " ISYS Capture %u",
 249				 i * NR_OF_CSI2_SRC_PADS + j);
 250			av->isys = isys;
 251			av->aq.vbq.buf_struct_size =
 252				sizeof(struct ipu6_isys_video_buffer);
 253
 254			ret = ipu6_isys_video_init(av);
 255			if (ret)
 256				goto fail;
 257		}
 258	}
 259
 260	return 0;
 261
 262fail:
 263	while (i--) {
 264		while (j--)
 265			ipu6_isys_video_cleanup(&isys->csi2[i].av[j]);
 266		j = NR_OF_CSI2_SRC_PADS;
 267	}
 268
 269	return ret;
 270}
 271
 272void isys_setup_hw(struct ipu6_isys *isys)
 273{
 274	void __iomem *base = isys->pdata->base;
 275	const u8 *thd = isys->pdata->ipdata->hw_variant.cdc_fifo_threshold;
 276	u32 irqs = 0;
 277	unsigned int i, nports;
 278
 279	nports = isys->pdata->ipdata->csi2.nports;
 280
 281	/* Enable irqs for all MIPI ports */
 282	for (i = 0; i < nports; i++)
 283		irqs |= IPU6_ISYS_UNISPART_IRQ_CSI2(i);
 284
 285	writel(irqs, base + isys->pdata->ipdata->csi2.ctrl0_irq_edge);
 286	writel(irqs, base + isys->pdata->ipdata->csi2.ctrl0_irq_lnp);
 287	writel(irqs, base + isys->pdata->ipdata->csi2.ctrl0_irq_mask);
 288	writel(irqs, base + isys->pdata->ipdata->csi2.ctrl0_irq_enable);
 289	writel(GENMASK(19, 0),
 290	       base + isys->pdata->ipdata->csi2.ctrl0_irq_clear);
 291
 292	irqs = ISYS_UNISPART_IRQS;
 293	writel(irqs, base + IPU6_REG_ISYS_UNISPART_IRQ_EDGE);
 294	writel(irqs, base + IPU6_REG_ISYS_UNISPART_IRQ_LEVEL_NOT_PULSE);
 295	writel(GENMASK(28, 0), base + IPU6_REG_ISYS_UNISPART_IRQ_CLEAR);
 296	writel(irqs, base + IPU6_REG_ISYS_UNISPART_IRQ_MASK);
 297	writel(irqs, base + IPU6_REG_ISYS_UNISPART_IRQ_ENABLE);
 298
 299	writel(0, base + IPU6_REG_ISYS_UNISPART_SW_IRQ_REG);
 300	writel(0, base + IPU6_REG_ISYS_UNISPART_SW_IRQ_MUX_REG);
 301
 302	/* Write CDC FIFO threshold values for isys */
 303	for (i = 0; i < isys->pdata->ipdata->hw_variant.cdc_fifos; i++)
 304		writel(thd[i], base + IPU6_REG_ISYS_CDC_THRESHOLD(i));
 305}
 306
 307static void ipu6_isys_csi2_isr(struct ipu6_isys_csi2 *csi2)
 308{
 309	struct ipu6_isys_stream *stream;
 310	unsigned int i;
 311	u32 status;
 312	int source;
 313
 314	ipu6_isys_register_errors(csi2);
 315
 316	status = readl(csi2->base + CSI_PORT_REG_BASE_IRQ_CSI_SYNC +
 317		       CSI_PORT_REG_BASE_IRQ_STATUS_OFFSET);
 318
 319	writel(status, csi2->base + CSI_PORT_REG_BASE_IRQ_CSI_SYNC +
 320	       CSI_PORT_REG_BASE_IRQ_CLEAR_OFFSET);
 321
 322	source = csi2->asd.source;
 323	for (i = 0; i < NR_OF_CSI2_VC; i++) {
 324		if (status & IPU_CSI_RX_IRQ_FS_VC(i)) {
 325			stream = ipu6_isys_query_stream_by_source(csi2->isys,
 326								  source, i);
 327			if (stream) {
 328				ipu6_isys_csi2_sof_event_by_stream(stream);
 329				ipu6_isys_put_stream(stream);
 330			}
 331		}
 332
 333		if (status & IPU_CSI_RX_IRQ_FE_VC(i)) {
 334			stream = ipu6_isys_query_stream_by_source(csi2->isys,
 335								  source, i);
 336			if (stream) {
 337				ipu6_isys_csi2_eof_event_by_stream(stream);
 338				ipu6_isys_put_stream(stream);
 339			}
 340		}
 341	}
 342}
 343
 344irqreturn_t isys_isr(struct ipu6_bus_device *adev)
 345{
 346	struct ipu6_isys *isys = ipu6_bus_get_drvdata(adev);
 347	void __iomem *base = isys->pdata->base;
 348	u32 status_sw, status_csi;
 349	u32 ctrl0_status, ctrl0_clear;
 350
 351	spin_lock(&isys->power_lock);
 352	if (!isys->power) {
 353		spin_unlock(&isys->power_lock);
 354		return IRQ_NONE;
 355	}
 356
 357	ctrl0_status = isys->pdata->ipdata->csi2.ctrl0_irq_status;
 358	ctrl0_clear = isys->pdata->ipdata->csi2.ctrl0_irq_clear;
 359
 360	status_csi = readl(isys->pdata->base + ctrl0_status);
 361	status_sw = readl(isys->pdata->base +
 362			  IPU6_REG_ISYS_UNISPART_IRQ_STATUS);
 363
 364	writel(ISYS_UNISPART_IRQS & ~IPU6_ISYS_UNISPART_IRQ_SW,
 365	       base + IPU6_REG_ISYS_UNISPART_IRQ_MASK);
 366
 367	do {
 368		writel(status_csi, isys->pdata->base + ctrl0_clear);
 369
 370		writel(status_sw, isys->pdata->base +
 371		       IPU6_REG_ISYS_UNISPART_IRQ_CLEAR);
 372
 373		if (isys->isr_csi2_bits & status_csi) {
 374			unsigned int i;
 375
 376			for (i = 0; i < isys->pdata->ipdata->csi2.nports; i++) {
 377				/* irq from not enabled port */
 378				if (!isys->csi2[i].base)
 379					continue;
 380				if (status_csi & IPU6_ISYS_UNISPART_IRQ_CSI2(i))
 381					ipu6_isys_csi2_isr(&isys->csi2[i]);
 382			}
 383		}
 384
 385		writel(0, base + IPU6_REG_ISYS_UNISPART_SW_IRQ_REG);
 386
 387		if (!isys_isr_one(adev))
 388			status_sw = IPU6_ISYS_UNISPART_IRQ_SW;
 389		else
 390			status_sw = 0;
 391
 392		status_csi = readl(isys->pdata->base + ctrl0_status);
 393		status_sw |= readl(isys->pdata->base +
 394				   IPU6_REG_ISYS_UNISPART_IRQ_STATUS);
 395	} while ((status_csi & isys->isr_csi2_bits) ||
 396		 (status_sw & IPU6_ISYS_UNISPART_IRQ_SW));
 397
 398	writel(ISYS_UNISPART_IRQS, base + IPU6_REG_ISYS_UNISPART_IRQ_MASK);
 399
 400	spin_unlock(&isys->power_lock);
 401
 402	return IRQ_HANDLED;
 403}
 404
 405static void get_lut_ltrdid(struct ipu6_isys *isys, struct ltr_did *pltr_did)
 406{
 407	struct isys_iwake_watermark *iwake_watermark = &isys->iwake_watermark;
 408	struct ltr_did ltrdid_default;
 409
 410	ltrdid_default.lut_ltr.value = LTR_DEFAULT_VALUE;
 411	ltrdid_default.lut_fill_time.value = FILL_TIME_DEFAULT_VALUE;
 412
 413	if (iwake_watermark->ltrdid.lut_ltr.value)
 414		*pltr_did = iwake_watermark->ltrdid;
 415	else
 416		*pltr_did = ltrdid_default;
 417}
 418
 419static int set_iwake_register(struct ipu6_isys *isys, u32 index, u32 value)
 420{
 421	struct device *dev = &isys->adev->auxdev.dev;
 422	u32 req_id = index;
 423	u32 offset = 0;
 424	int ret;
 425
 426	ret = ipu6_fw_isys_send_proxy_token(isys, req_id, index, offset, value);
 427	if (ret)
 428		dev_err(dev, "write %d failed %d", index, ret);
 429
 430	return ret;
 431}
 432
 433/*
 434 * When input system is powered up and before enabling any new sensor capture,
 435 * or after disabling any sensor capture the following values need to be set:
 436 * LTR_value = LTR(usec) from calculation;
 437 * LTR_scale = 2;
 438 * DID_value = DID(usec) from calculation;
 439 * DID_scale = 2;
 440 *
 441 * When input system is powered down, the LTR and DID values
 442 * must be returned to the default values:
 443 * LTR_value = 1023;
 444 * LTR_scale = 5;
 445 * DID_value = 1023;
 446 * DID_scale = 2;
 447 */
 448static void set_iwake_ltrdid(struct ipu6_isys *isys, u16 ltr, u16 did,
 449			     enum ltr_did_type use)
 450{
 451	struct device *dev = &isys->adev->auxdev.dev;
 452	u16 ltr_val, ltr_scale = LTR_SCALE_1024NS;
 453	u16 did_val, did_scale = DID_SCALE_1US;
 454	struct ipu6_device *isp = isys->adev->isp;
 455	union fabric_ctrl fc;
 456
 457	switch (use) {
 458	case LTR_IWAKE_ON:
 459		ltr_val = min_t(u16, ltr, (u16)LTR_DID_VAL_MAX);
 460		did_val = min_t(u16, did, (u16)LTR_DID_VAL_MAX);
 461		ltr_scale = (ltr == LTR_DID_VAL_MAX &&
 462			     did == LTR_DID_VAL_MAX) ?
 463			LTR_SCALE_DEFAULT : LTR_SCALE_1024NS;
 464		break;
 465	case LTR_ISYS_ON:
 466	case LTR_IWAKE_OFF:
 467		ltr_val = LTR_DID_PKGC_2R;
 468		did_val = LTR_DID_PKGC_2R;
 469		break;
 470	case LTR_ISYS_OFF:
 471		ltr_val   = LTR_DID_VAL_MAX;
 472		did_val   = LTR_DID_VAL_MAX;
 473		ltr_scale = LTR_SCALE_DEFAULT;
 474		break;
 475	case LTR_ENHANNCE_IWAKE:
 476		if (ltr == LTR_DID_VAL_MAX && did == LTR_DID_VAL_MAX) {
 477			ltr_val = LTR_DID_VAL_MAX;
 478			did_val = LTR_DID_VAL_MAX;
 479			ltr_scale = LTR_SCALE_DEFAULT;
 480		} else if (did < ONE_THOUSAND_MICROSECOND) {
 481			ltr_val = ltr;
 482			did_val = did;
 483		} else {
 484			ltr_val = ltr;
 485			/* div 90% value by 32 to account for scale change */
 486			did_val = did / 32;
 487			did_scale = DID_SCALE_32US;
 488		}
 489		break;
 490	default:
 491		ltr_val   = LTR_DID_VAL_MAX;
 492		did_val   = LTR_DID_VAL_MAX;
 493		ltr_scale = LTR_SCALE_DEFAULT;
 494		break;
 495	}
 496
 497	fc.value = readl(isp->base + IPU6_BUTTRESS_FABIC_CONTROL);
 498	fc.bits.ltr_val = ltr_val;
 499	fc.bits.ltr_scale = ltr_scale;
 500	fc.bits.did_val = did_val;
 501	fc.bits.did_scale = did_scale;
 502
 503	dev_dbg(dev, "ltr: value %u scale %u, did: value %u scale %u\n",
 504		ltr_val, ltr_scale, did_val, did_scale);
 505	writel(fc.value, isp->base + IPU6_BUTTRESS_FABIC_CONTROL);
 506}
 507
 508/*
 509 * Driver may clear register GDA_ENABLE_IWAKE before FW configures the
 510 * stream for debug purpose. Otherwise driver should not access this register.
 511 */
 512static void enable_iwake(struct ipu6_isys *isys, bool enable)
 513{
 514	struct isys_iwake_watermark *iwake_watermark = &isys->iwake_watermark;
 515	int ret;
 516
 517	mutex_lock(&iwake_watermark->mutex);
 518
 519	if (iwake_watermark->iwake_enabled == enable) {
 520		mutex_unlock(&iwake_watermark->mutex);
 521		return;
 522	}
 523
 524	ret = set_iwake_register(isys, GDA_ENABLE_IWAKE_INDEX, enable);
 525	if (!ret)
 526		iwake_watermark->iwake_enabled = enable;
 527
 528	mutex_unlock(&iwake_watermark->mutex);
 529}
 530
 531void update_watermark_setting(struct ipu6_isys *isys)
 532{
 533	struct isys_iwake_watermark *iwake_watermark = &isys->iwake_watermark;
 534	u32 iwake_threshold, iwake_critical_threshold, page_num;
 535	struct device *dev = &isys->adev->auxdev.dev;
 536	u32 calc_fill_time_us = 0, ltr = 0, did = 0;
 537	struct video_stream_watermark *p_watermark;
 538	enum ltr_did_type ltr_did_type;
 539	struct list_head *stream_node;
 540	u64 isys_pb_datarate_mbs = 0;
 541	u32 mem_open_threshold = 0;
 542	struct ltr_did ltrdid;
 543	u64 threshold_bytes;
 544	u32 max_sram_size;
 545	u32 shift;
 546
 547	shift = isys->pdata->ipdata->sram_gran_shift;
 548	max_sram_size = isys->pdata->ipdata->max_sram_size;
 549
 550	mutex_lock(&iwake_watermark->mutex);
 551	if (iwake_watermark->force_iwake_disable) {
 552		set_iwake_ltrdid(isys, 0, 0, LTR_IWAKE_OFF);
 553		set_iwake_register(isys, GDA_IRQ_CRITICAL_THRESHOLD_INDEX,
 554				   CRITICAL_THRESHOLD_IWAKE_DISABLE);
 555		goto unlock_exit;
 556	}
 557
 558	if (list_empty(&iwake_watermark->video_list)) {
 559		isys_pb_datarate_mbs = 0;
 560	} else {
 561		list_for_each(stream_node, &iwake_watermark->video_list) {
 562			p_watermark = list_entry(stream_node,
 563						 struct video_stream_watermark,
 564						 stream_node);
 565			isys_pb_datarate_mbs += p_watermark->stream_data_rate;
 566		}
 567	}
 568	mutex_unlock(&iwake_watermark->mutex);
 569
 570	if (!isys_pb_datarate_mbs) {
 571		enable_iwake(isys, false);
 572		set_iwake_ltrdid(isys, 0, 0, LTR_IWAKE_OFF);
 573		mutex_lock(&iwake_watermark->mutex);
 574		set_iwake_register(isys, GDA_IRQ_CRITICAL_THRESHOLD_INDEX,
 575				   CRITICAL_THRESHOLD_IWAKE_DISABLE);
 576		goto unlock_exit;
 577	}
 578
 579	enable_iwake(isys, true);
 580	calc_fill_time_us = div64_u64(max_sram_size, isys_pb_datarate_mbs);
 581
 582	if (isys->pdata->ipdata->enhanced_iwake) {
 583		ltr = isys->pdata->ipdata->ltr;
 584		did = calc_fill_time_us * DEFAULT_DID_RATIO / 100;
 585		ltr_did_type = LTR_ENHANNCE_IWAKE;
 586	} else {
 587		get_lut_ltrdid(isys, &ltrdid);
 588
 589		if (calc_fill_time_us <= ltrdid.lut_fill_time.bits.th0)
 590			ltr = 0;
 591		else if (calc_fill_time_us <= ltrdid.lut_fill_time.bits.th1)
 592			ltr = ltrdid.lut_ltr.bits.val0;
 593		else if (calc_fill_time_us <= ltrdid.lut_fill_time.bits.th2)
 594			ltr = ltrdid.lut_ltr.bits.val1;
 595		else if (calc_fill_time_us <= ltrdid.lut_fill_time.bits.th3)
 596			ltr = ltrdid.lut_ltr.bits.val2;
 597		else
 598			ltr = ltrdid.lut_ltr.bits.val3;
 599
 600		did = calc_fill_time_us - ltr;
 601		ltr_did_type = LTR_IWAKE_ON;
 602	}
 603
 604	set_iwake_ltrdid(isys, ltr, did, ltr_did_type);
 605
 606	/* calculate iwake threshold with 2KB granularity pages */
 607	threshold_bytes = did * isys_pb_datarate_mbs;
 608	iwake_threshold = max_t(u32, 1, threshold_bytes >> shift);
 609	iwake_threshold = min_t(u32, iwake_threshold, max_sram_size);
 610
 611	mutex_lock(&iwake_watermark->mutex);
 612	if (isys->pdata->ipdata->enhanced_iwake) {
 613		set_iwake_register(isys, GDA_IWAKE_THRESHOLD_INDEX,
 614				   DEFAULT_IWAKE_THRESHOLD);
 615		/* calculate number of pages that will be filled in 10 usec */
 616		page_num = (DEFAULT_MEM_OPEN_TIME * isys_pb_datarate_mbs) /
 617			ISF_DMA_TOP_GDA_PROFERTY_PAGE_SIZE;
 618		page_num += ((DEFAULT_MEM_OPEN_TIME * isys_pb_datarate_mbs) %
 619			     ISF_DMA_TOP_GDA_PROFERTY_PAGE_SIZE) ? 1 : 0;
 620		mem_open_threshold = isys->pdata->ipdata->memopen_threshold;
 621		mem_open_threshold = max_t(u32, mem_open_threshold, page_num);
 622		dev_dbg(dev, "mem_open_threshold: %u\n", mem_open_threshold);
 623		set_iwake_register(isys, GDA_MEMOPEN_THRESHOLD_INDEX,
 624				   mem_open_threshold);
 625	} else {
 626		set_iwake_register(isys, GDA_IWAKE_THRESHOLD_INDEX,
 627				   iwake_threshold);
 628	}
 629
 630	iwake_critical_threshold = iwake_threshold +
 631		(IS_PIXEL_BUFFER_PAGES - iwake_threshold) / 2;
 632
 633	dev_dbg(dev, "threshold: %u critical: %u\n", iwake_threshold,
 634		iwake_critical_threshold);
 635
 636	set_iwake_register(isys, GDA_IRQ_CRITICAL_THRESHOLD_INDEX,
 637			   iwake_critical_threshold);
 638
 639	writel(VAL_PKGC_PMON_CFG_RESET,
 640	       isys->adev->isp->base + REG_PKGC_PMON_CFG);
 641	writel(VAL_PKGC_PMON_CFG_START,
 642	       isys->adev->isp->base + REG_PKGC_PMON_CFG);
 643unlock_exit:
 644	mutex_unlock(&iwake_watermark->mutex);
 645}
 646
 647static void isys_iwake_watermark_init(struct ipu6_isys *isys)
 648{
 649	struct isys_iwake_watermark *iwake_watermark = &isys->iwake_watermark;
 650
 651	INIT_LIST_HEAD(&iwake_watermark->video_list);
 652	mutex_init(&iwake_watermark->mutex);
 653
 654	iwake_watermark->ltrdid.lut_ltr.value = 0;
 655	iwake_watermark->isys = isys;
 656	iwake_watermark->iwake_enabled = false;
 657	iwake_watermark->force_iwake_disable = false;
 658}
 659
 660static void isys_iwake_watermark_cleanup(struct ipu6_isys *isys)
 661{
 662	struct isys_iwake_watermark *iwake_watermark = &isys->iwake_watermark;
 663
 664	mutex_lock(&iwake_watermark->mutex);
 665	list_del(&iwake_watermark->video_list);
 666	mutex_unlock(&iwake_watermark->mutex);
 667
 668	mutex_destroy(&iwake_watermark->mutex);
 669}
 670
 671/* The .bound() notifier callback when a match is found */
 672static int isys_notifier_bound(struct v4l2_async_notifier *notifier,
 673			       struct v4l2_subdev *sd,
 674			       struct v4l2_async_connection *asc)
 675{
 676	struct ipu6_isys *isys =
 677		container_of(notifier, struct ipu6_isys, notifier);
 678	struct sensor_async_sd *s_asd =
 679		container_of(asc, struct sensor_async_sd, asc);
 680	int ret;
 681
 682	if (s_asd->csi2.port >= isys->pdata->ipdata->csi2.nports) {
 683		dev_err(&isys->adev->auxdev.dev, "invalid csi2 port %u\n",
 684			s_asd->csi2.port);
 685		return -EINVAL;
 686	}
 687
 688	ret = ipu_bridge_instantiate_vcm(sd->dev);
 689	if (ret) {
 690		dev_err(&isys->adev->auxdev.dev, "instantiate vcm failed\n");
 691		return ret;
 692	}
 693
 694	dev_dbg(&isys->adev->auxdev.dev, "bind %s nlanes is %d port is %d\n",
 695		sd->name, s_asd->csi2.nlanes, s_asd->csi2.port);
 696	ret = isys_complete_ext_device_registration(isys, sd, &s_asd->csi2);
 697	if (ret)
 698		return ret;
 699
 700	return v4l2_device_register_subdev_nodes(&isys->v4l2_dev);
 701}
 702
 703static int isys_notifier_complete(struct v4l2_async_notifier *notifier)
 704{
 705	struct ipu6_isys *isys =
 706		container_of(notifier, struct ipu6_isys, notifier);
 707
 708	return v4l2_device_register_subdev_nodes(&isys->v4l2_dev);
 709}
 710
 711static const struct v4l2_async_notifier_operations isys_async_ops = {
 712	.bound = isys_notifier_bound,
 713	.complete = isys_notifier_complete,
 714};
 715
 716#define ISYS_MAX_PORTS 8
 717static int isys_notifier_init(struct ipu6_isys *isys)
 718{
 719	struct ipu6_device *isp = isys->adev->isp;
 720	struct device *dev = &isp->pdev->dev;
 721	unsigned int i;
 722	int ret;
 723
 724	v4l2_async_nf_init(&isys->notifier, &isys->v4l2_dev);
 725
 726	for (i = 0; i < ISYS_MAX_PORTS; i++) {
 727		struct v4l2_fwnode_endpoint vep = {
 728			.bus_type = V4L2_MBUS_CSI2_DPHY
 729		};
 730		struct sensor_async_sd *s_asd;
 731		struct fwnode_handle *ep;
 732
 733		ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), i, 0,
 734						FWNODE_GRAPH_ENDPOINT_NEXT);
 735		if (!ep)
 736			continue;
 737
 738		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
 739		if (ret) {
 740			dev_err(dev, "fwnode endpoint parse failed: %d\n", ret);
 741			goto err_parse;
 742		}
 743
 744		s_asd = v4l2_async_nf_add_fwnode_remote(&isys->notifier, ep,
 745							struct sensor_async_sd);
 746		if (IS_ERR(s_asd)) {
 747			ret = PTR_ERR(s_asd);
 748			dev_err(dev, "add remove fwnode failed: %d\n", ret);
 749			goto err_parse;
 750		}
 751
 752		s_asd->csi2.port = vep.base.port;
 753		s_asd->csi2.nlanes = vep.bus.mipi_csi2.num_data_lanes;
 754
 755		dev_dbg(dev, "remote endpoint port %d with %d lanes added\n",
 756			s_asd->csi2.port, s_asd->csi2.nlanes);
 757
 758		fwnode_handle_put(ep);
 759
 760		continue;
 761
 762err_parse:
 763		fwnode_handle_put(ep);
 764		return ret;
 765	}
 766
 767	isys->notifier.ops = &isys_async_ops;
 768	ret = v4l2_async_nf_register(&isys->notifier);
 769	if (ret) {
 770		dev_err(dev, "failed to register async notifier : %d\n", ret);
 771		v4l2_async_nf_cleanup(&isys->notifier);
 772	}
 773
 774	return ret;
 775}
 776
 777static void isys_notifier_cleanup(struct ipu6_isys *isys)
 778{
 779	v4l2_async_nf_unregister(&isys->notifier);
 780	v4l2_async_nf_cleanup(&isys->notifier);
 781}
 782
 783static int isys_register_devices(struct ipu6_isys *isys)
 784{
 785	struct device *dev = &isys->adev->auxdev.dev;
 786	struct pci_dev *pdev = isys->adev->isp->pdev;
 787	int ret;
 788
 789	isys->media_dev.dev = dev;
 790	media_device_pci_init(&isys->media_dev,
 791			      pdev, IPU6_MEDIA_DEV_MODEL_NAME);
 792
 793	strscpy(isys->v4l2_dev.name, isys->media_dev.model,
 794		sizeof(isys->v4l2_dev.name));
 795
 796	ret = media_device_register(&isys->media_dev);
 797	if (ret < 0)
 798		goto out_media_device_unregister;
 799
 800	isys->v4l2_dev.mdev = &isys->media_dev;
 801	isys->v4l2_dev.ctrl_handler = NULL;
 802
 803	ret = v4l2_device_register(dev, &isys->v4l2_dev);
 804	if (ret < 0)
 805		goto out_media_device_unregister;
 806
 807	ret = isys_register_video_devices(isys);
 808	if (ret)
 809		goto out_v4l2_device_unregister;
 810
 811	ret = isys_csi2_register_subdevices(isys);
 812	if (ret)
 813		goto out_isys_unregister_video_device;
 814
 815	ret = isys_csi2_create_media_links(isys);
 816	if (ret)
 817		goto out_isys_unregister_subdevices;
 818
 819	ret = isys_notifier_init(isys);
 820	if (ret)
 821		goto out_isys_unregister_subdevices;
 822
 823	return 0;
 824
 825out_isys_unregister_subdevices:
 826	isys_csi2_unregister_subdevices(isys);
 827
 828out_isys_unregister_video_device:
 829	isys_unregister_video_devices(isys);
 830
 831out_v4l2_device_unregister:
 832	v4l2_device_unregister(&isys->v4l2_dev);
 833
 834out_media_device_unregister:
 835	media_device_unregister(&isys->media_dev);
 836	media_device_cleanup(&isys->media_dev);
 837
 838	dev_err(dev, "failed to register isys devices\n");
 839
 840	return ret;
 841}
 842
 843static void isys_unregister_devices(struct ipu6_isys *isys)
 844{
 845	isys_unregister_video_devices(isys);
 846	isys_csi2_unregister_subdevices(isys);
 847	v4l2_device_unregister(&isys->v4l2_dev);
 848	media_device_unregister(&isys->media_dev);
 849	media_device_cleanup(&isys->media_dev);
 850}
 851
 852static int isys_runtime_pm_resume(struct device *dev)
 853{
 854	struct ipu6_bus_device *adev = to_ipu6_bus_device(dev);
 855	struct ipu6_isys *isys = ipu6_bus_get_drvdata(adev);
 856	struct ipu6_device *isp = adev->isp;
 857	unsigned long flags;
 858	int ret;
 859
 860	if (!isys)
 861		return 0;
 862
 863	ret = ipu6_mmu_hw_init(adev->mmu);
 864	if (ret)
 865		return ret;
 866
 867	cpu_latency_qos_update_request(&isys->pm_qos, ISYS_PM_QOS_VALUE);
 868
 869	ret = ipu6_buttress_start_tsc_sync(isp);
 870	if (ret)
 871		return ret;
 872
 873	spin_lock_irqsave(&isys->power_lock, flags);
 874	isys->power = 1;
 875	spin_unlock_irqrestore(&isys->power_lock, flags);
 876
 877	isys_setup_hw(isys);
 878
 879	set_iwake_ltrdid(isys, 0, 0, LTR_ISYS_ON);
 880
 881	return 0;
 882}
 883
 884static int isys_runtime_pm_suspend(struct device *dev)
 885{
 886	struct ipu6_bus_device *adev = to_ipu6_bus_device(dev);
 887	struct ipu6_isys *isys;
 888	unsigned long flags;
 889
 890	isys = dev_get_drvdata(dev);
 891	if (!isys)
 892		return 0;
 893
 894	spin_lock_irqsave(&isys->power_lock, flags);
 895	isys->power = 0;
 896	spin_unlock_irqrestore(&isys->power_lock, flags);
 897
 898	mutex_lock(&isys->mutex);
 899	isys->need_reset = false;
 900	mutex_unlock(&isys->mutex);
 901
 902	isys->phy_termcal_val = 0;
 903	cpu_latency_qos_update_request(&isys->pm_qos, PM_QOS_DEFAULT_VALUE);
 904
 905	set_iwake_ltrdid(isys, 0, 0, LTR_ISYS_OFF);
 906
 907	ipu6_mmu_hw_cleanup(adev->mmu);
 908
 909	return 0;
 910}
 911
 912static int isys_suspend(struct device *dev)
 913{
 914	struct ipu6_isys *isys = dev_get_drvdata(dev);
 915
 916	/* If stream is open, refuse to suspend */
 917	if (isys->stream_opened)
 918		return -EBUSY;
 919
 920	return 0;
 921}
 922
 923static int isys_resume(struct device *dev)
 924{
 925	return 0;
 926}
 927
 928static const struct dev_pm_ops isys_pm_ops = {
 929	.runtime_suspend = isys_runtime_pm_suspend,
 930	.runtime_resume = isys_runtime_pm_resume,
 931	.suspend = isys_suspend,
 932	.resume = isys_resume,
 933};
 934
 935static void free_fw_msg_bufs(struct ipu6_isys *isys)
 936{
 937	struct isys_fw_msgs *fwmsg, *safe;
 938
 939	list_for_each_entry_safe(fwmsg, safe, &isys->framebuflist, head)
 940		ipu6_dma_free(isys->adev, sizeof(struct isys_fw_msgs), fwmsg,
 941			      fwmsg->dma_addr, 0);
 942
 943	list_for_each_entry_safe(fwmsg, safe, &isys->framebuflist_fw, head)
 944		ipu6_dma_free(isys->adev, sizeof(struct isys_fw_msgs), fwmsg,
 945			      fwmsg->dma_addr, 0);
 946}
 947
 948static int alloc_fw_msg_bufs(struct ipu6_isys *isys, int amount)
 949{
 950	struct isys_fw_msgs *addr;
 951	dma_addr_t dma_addr;
 952	unsigned long flags;
 953	unsigned int i;
 954
 955	for (i = 0; i < amount; i++) {
 956		addr = ipu6_dma_alloc(isys->adev, sizeof(*addr),
 957				      &dma_addr, GFP_KERNEL, 0);
 958		if (!addr)
 959			break;
 960		addr->dma_addr = dma_addr;
 961
 962		spin_lock_irqsave(&isys->listlock, flags);
 963		list_add(&addr->head, &isys->framebuflist);
 964		spin_unlock_irqrestore(&isys->listlock, flags);
 965	}
 966
 967	if (i == amount)
 968		return 0;
 969
 970	spin_lock_irqsave(&isys->listlock, flags);
 971	while (!list_empty(&isys->framebuflist)) {
 972		addr = list_first_entry(&isys->framebuflist,
 973					struct isys_fw_msgs, head);
 974		list_del(&addr->head);
 975		spin_unlock_irqrestore(&isys->listlock, flags);
 976		ipu6_dma_free(isys->adev, sizeof(struct isys_fw_msgs), addr,
 977			      addr->dma_addr, 0);
 978		spin_lock_irqsave(&isys->listlock, flags);
 979	}
 980	spin_unlock_irqrestore(&isys->listlock, flags);
 981
 982	return -ENOMEM;
 983}
 984
 985struct isys_fw_msgs *ipu6_get_fw_msg_buf(struct ipu6_isys_stream *stream)
 986{
 987	struct ipu6_isys *isys = stream->isys;
 988	struct device *dev = &isys->adev->auxdev.dev;
 989	struct isys_fw_msgs *msg;
 990	unsigned long flags;
 991	int ret;
 992
 993	spin_lock_irqsave(&isys->listlock, flags);
 994	if (list_empty(&isys->framebuflist)) {
 995		spin_unlock_irqrestore(&isys->listlock, flags);
 996		dev_dbg(dev, "Frame list empty\n");
 997
 998		ret = alloc_fw_msg_bufs(isys, 5);
 999		if (ret < 0)
1000			return NULL;
1001
1002		spin_lock_irqsave(&isys->listlock, flags);
1003		if (list_empty(&isys->framebuflist)) {
1004			spin_unlock_irqrestore(&isys->listlock, flags);
1005			dev_err(dev, "Frame list empty\n");
1006			return NULL;
1007		}
1008	}
1009	msg = list_last_entry(&isys->framebuflist, struct isys_fw_msgs, head);
1010	list_move(&msg->head, &isys->framebuflist_fw);
1011	spin_unlock_irqrestore(&isys->listlock, flags);
1012	memset(&msg->fw_msg, 0, sizeof(msg->fw_msg));
1013
1014	return msg;
1015}
1016
1017void ipu6_cleanup_fw_msg_bufs(struct ipu6_isys *isys)
1018{
1019	struct isys_fw_msgs *fwmsg, *fwmsg0;
1020	unsigned long flags;
1021
1022	spin_lock_irqsave(&isys->listlock, flags);
1023	list_for_each_entry_safe(fwmsg, fwmsg0, &isys->framebuflist_fw, head)
1024		list_move(&fwmsg->head, &isys->framebuflist);
1025	spin_unlock_irqrestore(&isys->listlock, flags);
1026}
1027
1028void ipu6_put_fw_msg_buf(struct ipu6_isys *isys, uintptr_t data)
1029{
1030	struct isys_fw_msgs *msg;
1031	unsigned long flags;
1032	void *ptr = (void *)data;
1033
1034	if (!ptr)
1035		return;
1036
1037	spin_lock_irqsave(&isys->listlock, flags);
1038	msg = container_of(ptr, struct isys_fw_msgs, fw_msg.dummy);
1039	list_move(&msg->head, &isys->framebuflist);
1040	spin_unlock_irqrestore(&isys->listlock, flags);
1041}
1042
1043static int isys_probe(struct auxiliary_device *auxdev,
1044		      const struct auxiliary_device_id *auxdev_id)
1045{
1046	const struct ipu6_isys_internal_csi2_pdata *csi2_pdata;
1047	struct ipu6_bus_device *adev = auxdev_to_adev(auxdev);
1048	struct ipu6_device *isp = adev->isp;
1049	const struct firmware *fw;
1050	struct ipu6_isys *isys;
1051	unsigned int i;
1052	int ret;
1053
1054	if (!isp->bus_ready_to_probe)
1055		return -EPROBE_DEFER;
1056
1057	isys = devm_kzalloc(&auxdev->dev, sizeof(*isys), GFP_KERNEL);
1058	if (!isys)
1059		return -ENOMEM;
1060
1061	adev->auxdrv_data =
1062		(const struct ipu6_auxdrv_data *)auxdev_id->driver_data;
1063	adev->auxdrv = to_auxiliary_drv(auxdev->dev.driver);
1064	isys->adev = adev;
1065	isys->pdata = adev->pdata;
1066	csi2_pdata = &isys->pdata->ipdata->csi2;
1067
1068	isys->csi2 = devm_kcalloc(&auxdev->dev, csi2_pdata->nports,
1069				  sizeof(*isys->csi2), GFP_KERNEL);
1070	if (!isys->csi2)
1071		return -ENOMEM;
1072
1073	ret = ipu6_mmu_hw_init(adev->mmu);
1074	if (ret)
1075		return ret;
1076
1077	/* initial sensor type */
1078	isys->sensor_type = isys->pdata->ipdata->sensor_type_start;
1079
1080	spin_lock_init(&isys->streams_lock);
1081	spin_lock_init(&isys->power_lock);
1082	isys->power = 0;
1083	isys->phy_termcal_val = 0;
1084
1085	mutex_init(&isys->mutex);
1086	mutex_init(&isys->stream_mutex);
1087
1088	spin_lock_init(&isys->listlock);
1089	INIT_LIST_HEAD(&isys->framebuflist);
1090	INIT_LIST_HEAD(&isys->framebuflist_fw);
1091
1092	isys->icache_prefetch = 0;
1093
1094	dev_set_drvdata(&auxdev->dev, isys);
1095
1096	isys_stream_init(isys);
1097
1098	if (!isp->secure_mode) {
1099		fw = isp->cpd_fw;
1100		ret = ipu6_buttress_map_fw_image(adev, fw, &adev->fw_sgt);
1101		if (ret)
1102			goto release_firmware;
1103
1104		ret = ipu6_cpd_create_pkg_dir(adev, isp->cpd_fw->data);
1105		if (ret)
1106			goto remove_shared_buffer;
1107	}
1108
1109	cpu_latency_qos_add_request(&isys->pm_qos, PM_QOS_DEFAULT_VALUE);
1110
1111	ret = alloc_fw_msg_bufs(isys, 20);
1112	if (ret < 0)
1113		goto out_remove_pkg_dir_shared_buffer;
1114
1115	isys_iwake_watermark_init(isys);
1116
1117	if (is_ipu6se(adev->isp->hw_ver))
1118		isys->phy_set_power = ipu6_isys_jsl_phy_set_power;
1119	else if (is_ipu6ep_mtl(adev->isp->hw_ver))
1120		isys->phy_set_power = ipu6_isys_dwc_phy_set_power;
1121	else
1122		isys->phy_set_power = ipu6_isys_mcd_phy_set_power;
1123
1124	ret = isys_register_devices(isys);
1125	if (ret)
1126		goto free_fw_msg_bufs;
1127
1128	ipu6_mmu_hw_cleanup(adev->mmu);
1129
1130	return 0;
1131
1132free_fw_msg_bufs:
1133	free_fw_msg_bufs(isys);
1134out_remove_pkg_dir_shared_buffer:
1135	cpu_latency_qos_remove_request(&isys->pm_qos);
1136	if (!isp->secure_mode)
1137		ipu6_cpd_free_pkg_dir(adev);
1138remove_shared_buffer:
1139	if (!isp->secure_mode)
1140		ipu6_buttress_unmap_fw_image(adev, &adev->fw_sgt);
1141release_firmware:
1142	if (!isp->secure_mode)
1143		release_firmware(adev->fw);
1144
1145	for (i = 0; i < IPU6_ISYS_MAX_STREAMS; i++)
1146		mutex_destroy(&isys->streams[i].mutex);
1147
1148	mutex_destroy(&isys->mutex);
1149	mutex_destroy(&isys->stream_mutex);
1150
1151	ipu6_mmu_hw_cleanup(adev->mmu);
1152
1153	return ret;
1154}
1155
1156static void isys_remove(struct auxiliary_device *auxdev)
1157{
1158	struct ipu6_bus_device *adev = auxdev_to_adev(auxdev);
1159	struct ipu6_isys *isys = dev_get_drvdata(&auxdev->dev);
1160	struct ipu6_device *isp = adev->isp;
1161	unsigned int i;
1162
1163	free_fw_msg_bufs(isys);
1164
1165	isys_unregister_devices(isys);
1166	isys_notifier_cleanup(isys);
1167
1168	cpu_latency_qos_remove_request(&isys->pm_qos);
1169
1170	if (!isp->secure_mode) {
1171		ipu6_cpd_free_pkg_dir(adev);
1172		ipu6_buttress_unmap_fw_image(adev, &adev->fw_sgt);
1173		release_firmware(adev->fw);
1174	}
1175
1176	for (i = 0; i < IPU6_ISYS_MAX_STREAMS; i++)
1177		mutex_destroy(&isys->streams[i].mutex);
1178
1179	isys_iwake_watermark_cleanup(isys);
1180	mutex_destroy(&isys->stream_mutex);
1181	mutex_destroy(&isys->mutex);
1182}
1183
1184struct fwmsg {
1185	int type;
1186	char *msg;
1187	bool valid_ts;
1188};
1189
1190static const struct fwmsg fw_msg[] = {
1191	{IPU6_FW_ISYS_RESP_TYPE_STREAM_OPEN_DONE, "STREAM_OPEN_DONE", 0},
1192	{IPU6_FW_ISYS_RESP_TYPE_STREAM_CLOSE_ACK, "STREAM_CLOSE_ACK", 0},
1193	{IPU6_FW_ISYS_RESP_TYPE_STREAM_START_ACK, "STREAM_START_ACK", 0},
1194	{IPU6_FW_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_ACK,
1195	 "STREAM_START_AND_CAPTURE_ACK", 0},
1196	{IPU6_FW_ISYS_RESP_TYPE_STREAM_STOP_ACK, "STREAM_STOP_ACK", 0},
1197	{IPU6_FW_ISYS_RESP_TYPE_STREAM_FLUSH_ACK, "STREAM_FLUSH_ACK", 0},
1198	{IPU6_FW_ISYS_RESP_TYPE_PIN_DATA_READY, "PIN_DATA_READY", 1},
1199	{IPU6_FW_ISYS_RESP_TYPE_STREAM_CAPTURE_ACK, "STREAM_CAPTURE_ACK", 0},
1200	{IPU6_FW_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_DONE,
1201	 "STREAM_START_AND_CAPTURE_DONE", 1},
1202	{IPU6_FW_ISYS_RESP_TYPE_STREAM_CAPTURE_DONE, "STREAM_CAPTURE_DONE", 1},
1203	{IPU6_FW_ISYS_RESP_TYPE_FRAME_SOF, "FRAME_SOF", 1},
1204	{IPU6_FW_ISYS_RESP_TYPE_FRAME_EOF, "FRAME_EOF", 1},
1205	{IPU6_FW_ISYS_RESP_TYPE_STATS_DATA_READY, "STATS_READY", 1},
1206	{-1, "UNKNOWN MESSAGE", 0}
1207};
1208
1209static u32 resp_type_to_index(int type)
1210{
1211	unsigned int i;
1212
1213	for (i = 0; i < ARRAY_SIZE(fw_msg); i++)
1214		if (fw_msg[i].type == type)
1215			return i;
1216
1217	return  ARRAY_SIZE(fw_msg) - 1;
1218}
1219
1220static int isys_isr_one(struct ipu6_bus_device *adev)
1221{
1222	struct ipu6_isys *isys = ipu6_bus_get_drvdata(adev);
1223	struct ipu6_fw_isys_resp_info_abi *resp;
1224	struct ipu6_isys_stream *stream;
1225	struct ipu6_isys_csi2 *csi2 = NULL;
1226	u32 index;
1227	u64 ts;
1228
1229	if (!isys->fwcom)
1230		return 1;
1231
1232	resp = ipu6_fw_isys_get_resp(isys->fwcom, IPU6_BASE_MSG_RECV_QUEUES);
1233	if (!resp)
1234		return 1;
1235
1236	ts = (u64)resp->timestamp[1] << 32 | resp->timestamp[0];
1237
1238	index = resp_type_to_index(resp->type);
1239	dev_dbg(&adev->auxdev.dev,
1240		"FW resp %02d %s, stream %u, ts 0x%16.16llx, pin %d\n",
1241		resp->type, fw_msg[index].msg, resp->stream_handle,
1242		fw_msg[index].valid_ts ? ts : 0, resp->pin_id);
1243
1244	if (resp->error_info.error == IPU6_FW_ISYS_ERROR_STREAM_IN_SUSPENSION)
1245		/* Suspension is kind of special case: not enough buffers */
1246		dev_dbg(&adev->auxdev.dev,
1247			"FW error resp SUSPENSION, details %d\n",
1248			resp->error_info.error_details);
1249	else if (resp->error_info.error)
1250		dev_dbg(&adev->auxdev.dev,
1251			"FW error resp error %d, details %d\n",
1252			resp->error_info.error, resp->error_info.error_details);
1253
1254	if (resp->stream_handle >= IPU6_ISYS_MAX_STREAMS) {
1255		dev_err(&adev->auxdev.dev, "bad stream handle %u\n",
1256			resp->stream_handle);
1257		goto leave;
1258	}
1259
1260	stream = ipu6_isys_query_stream_by_handle(isys, resp->stream_handle);
1261	if (!stream) {
1262		dev_err(&adev->auxdev.dev, "stream of stream_handle %u is unused\n",
1263			resp->stream_handle);
1264		goto leave;
1265	}
1266	stream->error = resp->error_info.error;
1267
1268	csi2 = ipu6_isys_subdev_to_csi2(stream->asd);
1269
1270	switch (resp->type) {
1271	case IPU6_FW_ISYS_RESP_TYPE_STREAM_OPEN_DONE:
1272		complete(&stream->stream_open_completion);
1273		break;
1274	case IPU6_FW_ISYS_RESP_TYPE_STREAM_CLOSE_ACK:
1275		complete(&stream->stream_close_completion);
1276		break;
1277	case IPU6_FW_ISYS_RESP_TYPE_STREAM_START_ACK:
1278		complete(&stream->stream_start_completion);
1279		break;
1280	case IPU6_FW_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_ACK:
1281		complete(&stream->stream_start_completion);
1282		break;
1283	case IPU6_FW_ISYS_RESP_TYPE_STREAM_STOP_ACK:
1284		complete(&stream->stream_stop_completion);
1285		break;
1286	case IPU6_FW_ISYS_RESP_TYPE_STREAM_FLUSH_ACK:
1287		complete(&stream->stream_stop_completion);
1288		break;
1289	case IPU6_FW_ISYS_RESP_TYPE_PIN_DATA_READY:
1290		/*
1291		 * firmware only release the capture msg until software
1292		 * get pin_data_ready event
1293		 */
1294		ipu6_put_fw_msg_buf(ipu6_bus_get_drvdata(adev), resp->buf_id);
1295		if (resp->pin_id < IPU6_ISYS_OUTPUT_PINS &&
1296		    stream->output_pins_queue[resp->pin_id])
1297			ipu6_isys_queue_buf_ready(stream, resp);
1298		else
1299			dev_warn(&adev->auxdev.dev,
1300				 "%d:No queue for pin id %d\n",
1301				 resp->stream_handle, resp->pin_id);
1302		if (csi2)
1303			ipu6_isys_csi2_error(csi2);
1304
1305		break;
1306	case IPU6_FW_ISYS_RESP_TYPE_STREAM_CAPTURE_ACK:
1307		break;
1308	case IPU6_FW_ISYS_RESP_TYPE_STREAM_START_AND_CAPTURE_DONE:
1309	case IPU6_FW_ISYS_RESP_TYPE_STREAM_CAPTURE_DONE:
1310		break;
1311	case IPU6_FW_ISYS_RESP_TYPE_FRAME_SOF:
1312
1313		ipu6_isys_csi2_sof_event_by_stream(stream);
1314		stream->seq[stream->seq_index].sequence =
1315			atomic_read(&stream->sequence) - 1;
1316		stream->seq[stream->seq_index].timestamp = ts;
1317		dev_dbg(&adev->auxdev.dev,
1318			"sof: handle %d: (index %u), timestamp 0x%16.16llx\n",
1319			resp->stream_handle,
1320			stream->seq[stream->seq_index].sequence, ts);
1321		stream->seq_index = (stream->seq_index + 1)
1322			% IPU6_ISYS_MAX_PARALLEL_SOF;
1323		break;
1324	case IPU6_FW_ISYS_RESP_TYPE_FRAME_EOF:
1325		ipu6_isys_csi2_eof_event_by_stream(stream);
1326		dev_dbg(&adev->auxdev.dev,
1327			"eof: handle %d: (index %u), timestamp 0x%16.16llx\n",
1328			resp->stream_handle,
1329			stream->seq[stream->seq_index].sequence, ts);
1330		break;
1331	case IPU6_FW_ISYS_RESP_TYPE_STATS_DATA_READY:
1332		break;
1333	default:
1334		dev_err(&adev->auxdev.dev, "%d:unknown response type %u\n",
1335			resp->stream_handle, resp->type);
1336		break;
1337	}
1338
1339	ipu6_isys_put_stream(stream);
1340leave:
1341	ipu6_fw_isys_put_resp(isys->fwcom, IPU6_BASE_MSG_RECV_QUEUES);
1342	return 0;
1343}
1344
1345static const struct ipu6_auxdrv_data ipu6_isys_auxdrv_data = {
1346	.isr = isys_isr,
1347	.isr_threaded = NULL,
1348	.wake_isr_thread = false,
1349};
1350
1351static const struct auxiliary_device_id ipu6_isys_id_table[] = {
1352	{
1353		.name = "intel_ipu6.isys",
1354		.driver_data = (kernel_ulong_t)&ipu6_isys_auxdrv_data,
1355	},
1356	{ }
1357};
1358MODULE_DEVICE_TABLE(auxiliary, ipu6_isys_id_table);
1359
1360static struct auxiliary_driver isys_driver = {
1361	.name = IPU6_ISYS_NAME,
1362	.probe = isys_probe,
1363	.remove = isys_remove,
1364	.id_table = ipu6_isys_id_table,
1365	.driver = {
1366		.pm = &isys_pm_ops,
1367	},
1368};
1369
1370module_auxiliary_driver(isys_driver);
1371
1372MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>");
1373MODULE_AUTHOR("Tianshu Qiu <tian.shu.qiu@intel.com>");
1374MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
1375MODULE_AUTHOR("Yunliang Ding <yunliang.ding@intel.com>");
1376MODULE_AUTHOR("Hongju Wang <hongju.wang@intel.com>");
1377MODULE_LICENSE("GPL");
1378MODULE_DESCRIPTION("Intel IPU6 input system driver");
1379MODULE_IMPORT_NS("INTEL_IPU6");
1380MODULE_IMPORT_NS("INTEL_IPU_BRIDGE");
~/ Read-only file preview.