drivers/gpu/drm/msm/dp/dp_aux.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/msm/dp/dp_aux.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/msm/dp/dp_aux.c
Extension
.c
Size
18383 bytes
Lines
730
Domain
Driver Families
Bucket
drivers/gpu
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

struct msm_dp_aux_private {
	struct device *dev;
	void __iomem *aux_base;

	struct phy *phy;

	struct mutex mutex;
	struct completion comp;

	enum msm_dp_aux_err aux_error_num;
	u32 retry_cnt;
	bool cmd_busy;
	bool native;
	bool read;
	bool no_send_addr;
	bool no_send_stop;
	bool initted;
	bool is_edp;
	bool enable_xfers;
	u32 offset;
	u32 segment;

	struct drm_dp_aux msm_dp_aux;
};

static inline u32 msm_dp_read_aux(struct msm_dp_aux_private *aux, u32 offset)
{
	return readl_relaxed(aux->aux_base + offset);
}

static inline void msm_dp_write_aux(struct msm_dp_aux_private *aux,
				u32 offset, u32 data)
{
	/*
	 * To make sure aux reg writes happens before any other operation,
	 * this function uses writel() instread of writel_relaxed()
	 */
	writel(data, aux->aux_base + offset);
}

static void msm_dp_aux_clear_hw_interrupts(struct msm_dp_aux_private *aux)
{
	msm_dp_read_aux(aux, REG_DP_PHY_AUX_INTERRUPT_STATUS);
	msm_dp_write_aux(aux, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x1f);
	msm_dp_write_aux(aux, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x9f);
	msm_dp_write_aux(aux, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0);
}

/*
 * NOTE: resetting AUX controller will also clear any pending HPD related interrupts
 */
static void msm_dp_aux_reset(struct msm_dp_aux_private *aux)
{
	u32 aux_ctrl;

	aux_ctrl = msm_dp_read_aux(aux, REG_DP_AUX_CTRL);

	aux_ctrl |= DP_AUX_CTRL_RESET;
	msm_dp_write_aux(aux, REG_DP_AUX_CTRL, aux_ctrl);
	usleep_range(1000, 1100); /* h/w recommended delay */

	aux_ctrl &= ~DP_AUX_CTRL_RESET;
	msm_dp_write_aux(aux, REG_DP_AUX_CTRL, aux_ctrl);
}

static void msm_dp_aux_enable(struct msm_dp_aux_private *aux)
{
	u32 aux_ctrl;

	aux_ctrl = msm_dp_read_aux(aux, REG_DP_AUX_CTRL);

	msm_dp_write_aux(aux, REG_DP_TIMEOUT_COUNT, 0xffff);
	msm_dp_write_aux(aux, REG_DP_AUX_LIMITS, 0xffff);

	aux_ctrl |= DP_AUX_CTRL_ENABLE;
	msm_dp_write_aux(aux, REG_DP_AUX_CTRL, aux_ctrl);
}

static void msm_dp_aux_disable(struct msm_dp_aux_private *aux)
{
	u32 aux_ctrl;

	aux_ctrl = msm_dp_read_aux(aux, REG_DP_AUX_CTRL);
	aux_ctrl &= ~DP_AUX_CTRL_ENABLE;
	msm_dp_write_aux(aux, REG_DP_AUX_CTRL, aux_ctrl);
}

static int msm_dp_aux_wait_for_hpd_connect_state(struct msm_dp_aux_private *aux,
					     unsigned long wait_us)
{

Annotation

Implementation Notes