drivers/media/platform/qcom/camss/camss-tpg-gen1.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/qcom/camss/camss-tpg-gen1.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/qcom/camss/camss-tpg-gen1.c
Extension
.c
Size
7641 bytes
Lines
232
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (tpg->hw_version == TPG_HW_VER_2_0_0) {
				val = FIELD_PREP(TPG_VC_m_DT_n_CFG_2_PAYLOAD_MODE, payload_mode) |
				      FIELD_PREP(TPG_V2_0_0_VC_m_DT_n_CFG_2_USER_SPECIFIED_PAYLOAD,
						 TPG_USER_SPECIFIED_PAYLOAD_DEFAULT) |
				      FIELD_PREP(TPG_V2_0_0_VC_m_DT_n_CFG_2_ENCODE_FORMAT,
						 format->encode_format);
			} else if (tpg->hw_version >= TPG_HW_VER_2_1_0) {
				val = FIELD_PREP(TPG_VC_m_DT_n_CFG_2_PAYLOAD_MODE, payload_mode) |
				      FIELD_PREP(TPG_V2_1_0_VC_m_DT_n_CFG_2_USER_SPECIFIED_PAYLOAD,
						 TPG_USER_SPECIFIED_PAYLOAD_DEFAULT) |
				      FIELD_PREP(TPG_V2_1_0_VC_m_DT_n_CFG_2_ENCODE_FORMAT,
						 format->encode_format);
			}
			writel(val, tpg->base + TPG_VC_m_DT_n_CFG_2(vc, dt));
		}
	}

	/* Global TPG control */
	val = FIELD_PREP(TPG_CTRL_TEST_EN, 1) |
	      FIELD_PREP(TPG_CTRL_NUM_ACTIVE_LANES, lane_cnt - 1) |
	      FIELD_PREP(TPG_CTRL_NUM_ACTIVE_VC, last_vc);
	writel(val, tpg->base + TPG_CTRL);

	return 0;
}

static int tpg_reset(struct tpg_device *tpg)
{
	writel(0, tpg->base + TPG_CTRL);
	writel(1, tpg->base + TPG_CLEAR);

	return 0;
}

static void tpg_stream_off(struct tpg_device *tpg)
{
	tpg_reset(tpg);
}

static int tpg_configure_stream(struct tpg_device *tpg, u8 enable)
{
	if (enable)
		return tpg_stream_on(tpg);

	tpg_stream_off(tpg);

	return 0;
}

static int tpg_configure_testgen_pattern(struct tpg_device *tpg, s32 val)
{
	if (val >= 0 && val <= TPG_PAYLOAD_MODE_COLOR_BARS)
		tpg->testgen.mode = val;

	return 0;
}

static u32 tpg_hw_version(struct tpg_device *tpg)
{
	u32 hw_version = readl(tpg->base + TPG_HW_VERSION);

	tpg->hw_version = hw_version;
	dev_dbg(tpg->camss->dev, "tpg HW Version = %u.%u.%u\n",
		(u32)FIELD_GET(HW_VERSION_GENERATION, hw_version),
		(u32)FIELD_GET(HW_VERSION_REVISION, hw_version),
		(u32)FIELD_GET(HW_VERSION_STEPPING, hw_version));

	return hw_version;
}

static void tpg_subdev_init(struct tpg_device *tpg)
{
	tpg->testgen.modes = testgen_payload_modes;
	tpg->testgen.nmodes = TPG_PAYLOAD_MODE_NUM_SUPPORTED_GEN1;
}

const struct tpg_hw_ops tpg_ops_gen1 = {
	.configure_stream = tpg_configure_stream,
	.configure_testgen_pattern = tpg_configure_testgen_pattern,
	.hw_version = tpg_hw_version,
	.reset = tpg_reset,
	.subdev_init = tpg_subdev_init,
};

Annotation

Implementation Notes