drivers/gpu/drm/loongson/lsdc_gfxpll.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/loongson/lsdc_gfxpll.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/loongson/lsdc_gfxpll.c
Extension
.c
Size
5964 bytes
Lines
200
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 loongson_gfxpll_bitmap {
	/* Byte 0 ~ Byte 3 */
	unsigned div_out_dc    : 7;  /*  6 : 0    DC output clock divider  */
	unsigned div_out_gmc   : 7;  /* 13 : 7    GMC output clock divider */
	unsigned div_out_gpu   : 7;  /* 20 : 14   GPU output clock divider */
	unsigned loopc         : 9;  /* 29 : 21   clock multiplier         */
	unsigned _reserved_1_  : 2;  /* 31 : 30                            */

	/* Byte 4 ~ Byte 7 */
	unsigned div_ref       : 7;   /* 38 : 32   Input clock divider    */
	unsigned locked        : 1;   /* 39        PLL locked indicator   */
	unsigned sel_out_dc    : 1;   /* 40        dc output clk enable   */
	unsigned sel_out_gmc   : 1;   /* 41        gmc output clk enable  */
	unsigned sel_out_gpu   : 1;   /* 42        gpu output clk enable  */
	unsigned set_param     : 1;   /* 43        Trigger the update     */
	unsigned bypass        : 1;   /* 44                               */
	unsigned powerdown     : 1;   /* 45                               */
	unsigned _reserved_2_  : 18;  /* 46 : 63   no use                 */
};

union loongson_gfxpll_reg_bitmap {
	struct loongson_gfxpll_bitmap bitmap;
	u32 w[2];
	u64 d;
};

static void __gfxpll_rreg(struct loongson_gfxpll *this,
			  union loongson_gfxpll_reg_bitmap *reg)
{
#if defined(CONFIG_64BIT)
	reg->d = readq(this->mmio);
#else
	reg->w[0] = readl(this->mmio);
	reg->w[1] = readl(this->mmio + 4);
#endif
}

/* Update new parameters to the hardware */

static int loongson_gfxpll_update(struct loongson_gfxpll * const this,
				  struct loongson_gfxpll_parms const *pin)
{
	/* None, TODO */

	return 0;
}

static void loongson_gfxpll_get_rates(struct loongson_gfxpll * const this,
				      unsigned int *dc,
				      unsigned int *gmc,
				      unsigned int *gpu)
{
	struct loongson_gfxpll_parms *pparms = &this->parms;
	union loongson_gfxpll_reg_bitmap gfxpll_reg;
	unsigned int pre_output;
	unsigned int dc_mhz;
	unsigned int gmc_mhz;
	unsigned int gpu_mhz;

	__gfxpll_rreg(this, &gfxpll_reg);

	pparms->div_ref = gfxpll_reg.bitmap.div_ref;
	pparms->loopc = gfxpll_reg.bitmap.loopc;

	pparms->div_out_dc = gfxpll_reg.bitmap.div_out_dc;
	pparms->div_out_gmc = gfxpll_reg.bitmap.div_out_gmc;
	pparms->div_out_gpu = gfxpll_reg.bitmap.div_out_gpu;

	pre_output = pparms->ref_clock / pparms->div_ref * pparms->loopc;

	dc_mhz = pre_output / pparms->div_out_dc / 1000;
	gmc_mhz = pre_output / pparms->div_out_gmc / 1000;
	gpu_mhz = pre_output / pparms->div_out_gpu / 1000;

	if (dc)
		*dc = dc_mhz;

	if (gmc)
		*gmc = gmc_mhz;

	if (gpu)
		*gpu = gpu_mhz;
}

static void loongson_gfxpll_print(struct loongson_gfxpll * const this,
				  struct drm_printer *p,
				  bool verbose)
{
	struct loongson_gfxpll_parms *parms = &this->parms;
	unsigned int dc, gmc, gpu;

Annotation

Implementation Notes