u-boot之logo show

位于u-boot\drivers\video\drm\rockchip_display.c 函数 display_logo:
 

static int display_logo(struct display_state *state)
{
	struct crtc_state *crtc_state = &state->crtc_state;
	struct connector_state *conn_state = &state->conn_state;
	struct logo_info *logo = &state->logo;
	int hdisplay, vdisplay;

	display_init(state);
	if (!state->is_init)
		return -ENODEV;

	switch (logo->bpp) {
	case 16:
		crtc_state->format = ROCKCHIP_FMT_RGB565;
		break;
	case 24:
		crtc_state->format = ROCKCHIP_FMT_RGB888;
		break;
	case 32:
		crtc_state->format = ROCKCHIP_FMT_ARGB8888;
		break;
	default:
		printf("can't support bmp bits[%d]\n", logo->bpp);
		return -EINVAL;
	}
	crtc_state->rb_swap = logo->bpp != 32;
	hdisplay = conn_state->mode.hdisplay;
	vdisplay = conn_state->mode.vdisplay;
	crtc_state->src_w = logo->width;
	crtc_state->src_h = logo->height;
	crtc_state->src_x = 0;
	crtc_state->src_y = 0;
	crtc_state->ymirror = logo->ymirror;

	crtc_state->dma_addr = (u32)(unsigned long)logo->mem + logo->offset;
	crtc_state->xvir = ALIGN(crtc_state->src_w * logo->bpp, 32) >> 5;

	if (logo->mode == ROCKCHIP_DISPLAY_FULLSCREEN) {
		crtc_state->crtc_x = 0;
		crtc_state->crtc_y = 0;
		crtc_state->crtc_w = hdisplay;
		crtc_state->crtc_h = vdisplay;
	} else {
		if (crtc_state->src_w >= hdisplay) {
			crtc_state->crtc_x = 0;
			crtc_state->crtc_w = hdisplay;
		} else {
			crtc_state->crtc_x = (hdisplay - crtc_state->src_w) / 2;
			crtc_state->crtc_w = crtc_state->src_w;
		}

		if (crtc_state->src_h >= vdisplay) {
			crtc_state->crtc_y = 0;
			crtc_state->crtc_h = vdisplay;
		} else {
			crtc_state->crtc_y = (vdisplay - crtc_state->src_h) / 2;
			crtc_state->crtc_h = crtc_state->src_h;
		}
	}

	display_set_plane(state);
	display_enable(state);

	return 0;
}

1. display_init: 初始化panel,注册相关函数;初始化connector,注册相关函数,检测连接器插入设备;获取显示控制时序或读取edid,设置扫描模式。
 

static int display_init(struct display_state *state)
{
	struct connector_state *conn_state = &state->conn_state;
	struct panel_state *panel_state = &state->panel_state;
	const struct rockchip_connector *conn = conn_state->connector;
	const struct rockchip_connector_funcs *conn_funcs = conn->funcs;
	struct crtc_state *crtc_state = &state->crtc_state;
	struct rockchip_crtc *crtc = crtc_state->crtc;
	const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs;
	struct drm_display_mode *mode = &conn_state->mode;
	int bpc;
	int ret = 0;
	static bool __print_once = false;

	if (!__print_once) {
		__print_once = true;
		printf("Rockchip UBOOT DRM driver version: %s\n", DRIVER_VERSION);
	}

	if (state->is_init)
		return 0;

	if (!conn_funcs || !crtc_funcs) {
		printf("failed to find connector or crtc functions\n");
		return -ENXIO;
	}

	if (panel_state->panel)
		rockchip_panel_init(panel_state->panel);

	if (conn_funcs->init) {
		ret = conn_funcs->init(state);
		if (ret)
			goto deinit;
	}

	if (conn_state->phy)
		rockchip_phy_init(conn_state->phy);

	/*
	 * support hotplug, but not connect;
	 */
#ifdef CONFIG_ROCKCHIP_DRM_TVE
	if (crtc->hdmi_hpd && conn_state->type == DRM_MODE_CONNECTOR_TV) {
		printf("hdmi plugin ,skip tve\n");
		goto deinit;
	}
#elif defined(CONFIG_DRM_ROCKCHIP_RK1000)
	if (crtc->hdmi_hpd && conn_state->type == DRM_MODE_CONNECTOR_LVDS) {
		printf("hdmi plugin ,skip tve\n");
		goto deinit;
	}
#endif
	if (conn_funcs->detect) {
		ret = conn_funcs->detect(state);
#if defined(CONFIG_ROCKCHIP_DRM_TVE) || defined(CONFIG_DRM_ROCKCHIP_RK1000)
		if (conn_state->type == DRM_MODE_CONNECTOR_HDMIA)
			crtc->hdmi_hpd = ret;
#endif
		if (!ret)
			goto deinit;
	}

	if (panel_state->panel) {
		ret = display_get_timing(state);
	} else if (conn_state->bridge) {
		ret = video_bridge_read_edid(conn_state->bridge->dev,
					     conn_state->edid, EDID_SIZE);
		if (ret > 0) {
			ret = edid_get_drm_mode(conn_state->edid, ret, mode,
						&bpc);
			if (!ret)
				edid_print_info((void *)&conn_state->edid);
		} else {
			ret = video_bridge_get_timing(conn_state->bridge->dev);
		}
	} else if (conn_funcs->get_timing) {
		ret = conn_funcs->get_timing(state);
	} else if (conn_funcs->get_edid) {
		ret = conn_funcs->get_edid(state);
		if (!ret) {
			ret = edid_get_drm_mode((void *)&conn_state->edid,
						sizeof(conn_state->edid), mode,
						&bpc);
			if (!ret)
				edid_print_info((void *)&conn_state->edid);
		}
	}

	if (ret)
		goto deinit;

	drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);

	if (crtc_funcs->init) {
		ret = crtc_funcs->init(state);
		if (ret)
			goto deinit;
	}
	state->is_init = 1;

	return 0;

deinit:
	if (conn_funcs->deinit)
		conn_funcs->deinit(state);
	return ret;
}

2.设置帧缓冲属性,如格式RGB565,RGB888或ARGB8888,设置分辨率大小及帧起始地址。将帧缓冲注册到plane,使能显示面板,开始显示。
3.display_set_plane:注册显示缓冲到面板
 

static int display_set_plane(struct display_state *state)
{
	struct crtc_state *crtc_state = &state->crtc_state;
	const struct rockchip_crtc *crtc = crtc_state->crtc;
	const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs;
	int ret;

	if (!state->is_init)
		return -EINVAL;

	if (crtc_funcs->set_plane) {
		ret = crtc_funcs->set_plane(state);
		if (ret)
			return ret;
	}

	return 0;
}


4.display_enable: 使能显示
 

static int display_enable(struct display_state *state)
{
	struct connector_state *conn_state = &state->conn_state;
	const struct rockchip_connector *conn = conn_state->connector;
	const struct rockchip_connector_funcs *conn_funcs = conn->funcs;
	struct crtc_state *crtc_state = &state->crtc_state;
	const struct rockchip_crtc *crtc = crtc_state->crtc;
	const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs;
	struct panel_state *panel_state = &state->panel_state;

	display_init(state);

	if (!state->is_init)
		return -EINVAL;

	if (state->is_enable)
		return 0;

	if (crtc_funcs->prepare)
		crtc_funcs->prepare(state);

	if (conn_funcs->prepare)
		conn_funcs->prepare(state);

	if (conn_state->bridge)
		rockchip_bridge_pre_enable(conn_state->bridge);

	if (panel_state->panel)
		rockchip_panel_prepare(panel_state->panel);

	if (crtc_funcs->enable)
		crtc_funcs->enable(state);

	if (conn_funcs->enable)
		conn_funcs->enable(state);

	if (conn_state->bridge)
		rockchip_bridge_enable(conn_state->bridge);

	if (panel_state->panel)
		rockchip_panel_enable(panel_state->panel);

	state->is_enable = true;

	return 0;
}

 

你可能感兴趣的:(平台硬件驱动)