drivers/gpu/drm/kmb/kmb_crtc.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/kmb/kmb_crtc.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/kmb/kmb_crtc.c
Extension
.c
Size
7461 bytes
Lines
249
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 kmb_crtc_timing {
	u32 vfront_porch;
	u32 vback_porch;
	u32 vsync_len;
	u32 hfront_porch;
	u32 hback_porch;
	u32 hsync_len;
};

static int kmb_crtc_enable_vblank(struct drm_crtc *crtc)
{
	struct drm_device *dev = crtc->dev;
	struct kmb_drm_private *kmb = to_kmb(dev);

	/* Clear interrupt */
	kmb_write_lcd(kmb, LCD_INT_CLEAR, LCD_INT_VERT_COMP);
	/* Set which interval to generate vertical interrupt */
	kmb_write_lcd(kmb, LCD_VSTATUS_COMPARE,
		      LCD_VSTATUS_COMPARE_VSYNC);
	/* Enable vertical interrupt */
	kmb_set_bitmask_lcd(kmb, LCD_INT_ENABLE,
			    LCD_INT_VERT_COMP);
	return 0;
}

static void kmb_crtc_disable_vblank(struct drm_crtc *crtc)
{
	struct drm_device *dev = crtc->dev;
	struct kmb_drm_private *kmb = to_kmb(dev);

	/* Clear interrupt */
	kmb_write_lcd(kmb, LCD_INT_CLEAR, LCD_INT_VERT_COMP);
	/* Disable vertical interrupt */
	kmb_clr_bitmask_lcd(kmb, LCD_INT_ENABLE,
			    LCD_INT_VERT_COMP);
}

static const struct drm_crtc_funcs kmb_crtc_funcs = {
	.destroy = drm_crtc_cleanup,
	.set_config = drm_atomic_helper_set_config,
	.page_flip = drm_atomic_helper_page_flip,
	.reset = drm_atomic_helper_crtc_reset,
	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
	.enable_vblank = kmb_crtc_enable_vblank,
	.disable_vblank = kmb_crtc_disable_vblank,
};

static void kmb_crtc_set_mode(struct drm_crtc *crtc,
			      struct drm_atomic_commit *old_state)
{
	struct drm_device *dev = crtc->dev;
	struct drm_display_mode *m = &crtc->state->adjusted_mode;
	struct kmb_crtc_timing vm;
	struct kmb_drm_private *kmb = to_kmb(dev);
	unsigned int val = 0;

	/* Initialize mipi */
	kmb_dsi_mode_set(kmb->kmb_dsi, m, kmb->sys_clk_mhz, old_state);
	drm_info(dev,
		 "vfp= %d vbp= %d vsync_len=%d hfp=%d hbp=%d hsync_len=%d\n",
		 m->crtc_vsync_start - m->crtc_vdisplay,
		 m->crtc_vtotal - m->crtc_vsync_end,
		 m->crtc_vsync_end - m->crtc_vsync_start,
		 m->crtc_hsync_start - m->crtc_hdisplay,
		 m->crtc_htotal - m->crtc_hsync_end,
		 m->crtc_hsync_end - m->crtc_hsync_start);
	val = kmb_read_lcd(kmb, LCD_INT_ENABLE);
	kmb_clr_bitmask_lcd(kmb, LCD_INT_ENABLE, val);
	kmb_set_bitmask_lcd(kmb, LCD_INT_CLEAR, ~0x0);
	vm.vfront_porch = 2;
	vm.vback_porch = 2;
	vm.vsync_len = 8;
	vm.hfront_porch = 0;
	vm.hback_porch = 0;
	vm.hsync_len = 28;

	drm_dbg(dev, "%s : %dactive height= %d vbp=%d vfp=%d vsync-w=%d h-active=%d h-bp=%d h-fp=%d hsync-l=%d",
		__func__, __LINE__,
			m->crtc_vdisplay, vm.vback_porch, vm.vfront_porch,
			vm.vsync_len, m->crtc_hdisplay, vm.hback_porch,
			vm.hfront_porch, vm.hsync_len);
	kmb_write_lcd(kmb, LCD_V_ACTIVEHEIGHT,
		      m->crtc_vdisplay - 1);
	kmb_write_lcd(kmb, LCD_V_BACKPORCH, vm.vback_porch);
	kmb_write_lcd(kmb, LCD_V_FRONTPORCH, vm.vfront_porch);
	kmb_write_lcd(kmb, LCD_VSYNC_WIDTH, vm.vsync_len - 1);
	kmb_write_lcd(kmb, LCD_H_ACTIVEWIDTH,
		      m->crtc_hdisplay - 1);
	kmb_write_lcd(kmb, LCD_H_BACKPORCH, vm.hback_porch);

Annotation

Implementation Notes