drivers/soc/mediatek/mtk-cmdq-helper.c

Source file repositories/reference/linux-study-clean/drivers/soc/mediatek/mtk-cmdq-helper.c

File Facts

System
Linux kernel
Corpus path
drivers/soc/mediatek/mtk-cmdq-helper.c
Extension
.c
Size
14840 bytes
Lines
598
Domain
Driver Families
Bucket
drivers/soc
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

struct cmdq_instruction {
	union {
		u32 value;
		u32 mask;
		struct {
			u16 arg_c;
			u16 src_reg;
		};
	};
	union {
		u16 offset;
		u16 event;
		u16 reg_dst;
	};
	union {
		u8 subsys;
		struct {
			u8 sop:5;
			u8 arg_c_t:1;
			u8 src_t:1;
			u8 dst_t:1;
		};
	};
	u8 op;
};

static inline u8 cmdq_operand_get_type(struct cmdq_operand *op)
{
	return op->reg ? CMDQ_REG_TYPE : CMDQ_IMMEDIATE_VALUE;
}

static inline u16 cmdq_operand_get_idx_value(struct cmdq_operand *op)
{
	return op->reg ? op->idx : op->value;
}

int cmdq_dev_get_client_reg(struct device *dev,
			    struct cmdq_client_reg *client_reg, int idx)
{
	struct of_phandle_args spec;
	struct resource res;
	int err;

	if (!client_reg)
		return -ENOENT;

	err = of_address_to_resource(dev->of_node, 0, &res);
	if (err) {
		dev_err(dev, "Missing reg in %s node\n", dev->of_node->full_name);
		return -EINVAL;
	}
	client_reg->pa_base = res.start;

	err = of_parse_phandle_with_fixed_args(dev->of_node,
					       "mediatek,gce-client-reg",
					       3, idx, &spec);
	if (err < 0) {
		dev_dbg(dev,
			"error %d can't parse gce-client-reg property (%d)",
			err, idx);

		/* make subsys invalid */
		client_reg->subsys = CMDQ_SUBSYS_INVALID;

		/*
		 * All GCEs support writing register PA with mask without subsys,
		 * but this requires extra GCE instructions to convert the PA into
		 * a format that GCE can handle, which is less performance than
		 * directly using subsys. Therefore, when subsys is available,
		 * we prefer to use subsys for writing register PA.
		 */
		client_reg->pkt_write = cmdq_pkt_write_pa;
		client_reg->pkt_write_mask = cmdq_pkt_write_mask_pa;

		return 0;
	}

	client_reg->subsys = (u8)spec.args[0];
	client_reg->offset = (u16)spec.args[1];
	client_reg->size = (u16)spec.args[2];
	of_node_put(spec.np);

	client_reg->pkt_write = cmdq_pkt_write_subsys;
	client_reg->pkt_write_mask = cmdq_pkt_write_mask_subsys;

	return 0;
}
EXPORT_SYMBOL(cmdq_dev_get_client_reg);

struct cmdq_client *cmdq_mbox_create(struct device *dev, int index)

Annotation

Implementation Notes