Exemplo n.º 1
0
void OMAPLFBDisplayInit(void)
{
    struct omap_overlay*         overlayptr = 0;
    unsigned int                 i = 0;
    unsigned int                 numoverlays = 0;

    // there is tv and lcd managers... we only care about lcd at this time.
    lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD);
#ifdef CONFIG_TVOUT_SHOLEST
    tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV);
#endif
    if(!lcd_mgr)
    {
        DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": OMAPLFBSetDisplayInfo couldn't find lcd overlay manager\n"));
        return;
    }

    numoverlays = omap_dss_get_num_overlays();
    if( numoverlays == 0)
    {
        DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": OMAPLFBSetDisplayInfo couldn't find any overlays\n"));
        return;
    }

    for( i = 0; i < numoverlays; i++ )
    {
        overlayptr = omap_dss_get_overlay(i);
        if( strncmp( overlayptr->name, "gfx", 3 ) == 0)
        {
            DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": OMAPLFBSetDisplayInfo found GFX overlay\n"));
            omap_gfxoverlay = overlayptr;
            break;
        }
    }
#ifdef CONFIG_TVOUT_SHOLEST
        for( i = 0; i < numoverlays; i++ )
        {
            overlayptr = omap_dss_get_overlay(i);
            if( strncmp( overlayptr->name, "vid2", 4 ) == 0)
            {
                DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": OMAPLFBSetDisplayInfo found GFX overlay\n"));
                omap_vid2overlay = overlayptr;
                break;
            }
        }

#endif
    if( omap_gfxoverlay == 0 )
    {
        DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": OMAPLFBSetDisplayInfo GFX overlay no found\n"));
        return;
    }

    omap_gfxoverlay->get_overlay_info( omap_gfxoverlay, &gfxoverlayinfo );
#ifdef CONFIG_TVOUT_SHOLEST
    omap_vid2overlay->get_overlay_info(omap_vid2overlay, &vid2overlayinfo);
#endif
    fb_info =  registered_fb[0];

}
Exemplo n.º 2
0
static int omapvout_dss_get_overlays(struct omap_overlay **gfx,
			struct omap_overlay **vid1, struct omap_overlay **vid2)
{
	struct omap_overlay *t;
	int num_ovlys;
	int i;

	*gfx = NULL;
	*vid1 = NULL;
	*vid2 = NULL;
	num_ovlys = omap_dss_get_num_overlays();
	for (i = 0; i < num_ovlys; i++) {
		t = omap_dss_get_overlay(i);

		switch (t->id) {
		case OMAP_DSS_GFX:
			*gfx = t;
			break;
		case OMAP_DSS_VIDEO1:
			*vid1 = t;
			break;
		case OMAP_DSS_VIDEO2:
			*vid2 = t;
			break;
		}
	}

	if (*gfx && *vid1 && *vid2)
		return 0;

	return -EINVAL;
}
Exemplo n.º 3
0
/* connect overlays to the new device, if not already connected. if force
 * selected, connect always. */
void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
{
	int i;
	struct omap_overlay_manager *lcd_mgr;
	struct omap_overlay_manager *tv_mgr;
	struct omap_overlay_manager *lcd2_mgr = NULL;
	struct omap_overlay_manager *mgr = NULL;

	lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD);
	tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV);
	if (cpu_is_omap44xx())
		lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2);

	if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
		if(lcd2_mgr == NULL) return; //LGE_CHANGE [[email protected]] 2011-03-02, P920 : For WBT
		if (!lcd2_mgr->device || force) {
			if (lcd2_mgr->device)
				lcd2_mgr->unset_device(lcd2_mgr);
			lcd2_mgr->set_device(lcd2_mgr, dssdev);
			mgr = lcd2_mgr;
		}
	} else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
		&& dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
		if (!lcd_mgr->device || force) {
			if (lcd_mgr->device)
				lcd_mgr->unset_device(lcd_mgr);
			lcd_mgr->set_device(lcd_mgr, dssdev);
			mgr = lcd_mgr;
		}
	}

	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
		|| dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
		if (!tv_mgr->device || force) {
			if (tv_mgr->device)
				tv_mgr->unset_device(tv_mgr);
			tv_mgr->set_device(tv_mgr, dssdev);
			mgr = tv_mgr;
		}
	}

//LGE_CHANGE_S [[email protected]] 2010-1-03, P920 : prevent to blink .
	if(dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
//LGE_CHANGE_E [[email protected]] 2011-01-03
		if (mgr) {
			for (i = 0; i < MAX_DSS_OVERLAYS; i++) {
				struct omap_overlay *ovl;
				ovl = omap_dss_get_overlay(i);
				if (!ovl->manager || force) {
					if (ovl->manager)
						omap_dss_unset_manager(ovl);
					omap_dss_set_manager(ovl, mgr);
				}
			}
		}
//LGE_CHANGE_S [[email protected]] 2010-1-03, P920 : prevent to blink .
	}
//LGE_CHANGE_E [[email protected]] 2011-01-03
}
Exemplo n.º 4
0
/* connect overlays to the new device, if not already connected. if force
 * selected, connect always. */
void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
{
	int i;
	struct omap_overlay_manager *lcd_mgr;
	struct omap_overlay_manager *tv_mgr;
	struct omap_overlay_manager *lcd2_mgr = NULL;
	struct omap_overlay_manager *mgr = NULL;

	lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD);
	tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV);
	if (dss_has_feature(FEAT_MGR_LCD2))
		lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2);

	if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
		if (!lcd2_mgr->device || force) {
			if (lcd2_mgr->device)
				lcd2_mgr->unset_device(lcd2_mgr);
			lcd2_mgr->set_device(lcd2_mgr, dssdev);
			mgr = lcd2_mgr;
		}
	} else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
			&& dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
		if (!lcd_mgr->device || force) {
			if (lcd_mgr->device)
				lcd_mgr->unset_device(lcd_mgr);
			lcd_mgr->set_device(lcd_mgr, dssdev);
			mgr = lcd_mgr;
		}
	}

	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
			|| dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
		if (!tv_mgr->device || force) {
			if (tv_mgr->device)
				tv_mgr->unset_device(tv_mgr);
			tv_mgr->set_device(tv_mgr, dssdev);
			mgr = tv_mgr;
		}
	}

	if (mgr) {
		dispc_runtime_get();

		for (i = 0; i < dss_feat_get_num_ovls(); i++) {
			struct omap_overlay *ovl;
			ovl = omap_dss_get_overlay(i);
			if (!ovl->manager || force) {
				if (ovl->manager)
					ovl->unset_manager(ovl);
				ovl->set_manager(ovl, mgr);
			}
		}

		dispc_runtime_put();
	}
}
Exemplo n.º 5
0
static void GetLcdManager(void){

    struct omap_overlay *ovl;
    ovl = omap_dss_get_overlay(0);
    lcd_mgr = omap_dss_get_overlay_manager(ovl->manager->id);
    if(!lcd_mgr)
    {
        DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": GetLcdManager couldn't find lcd overlay manager\n"));
    }
}
Exemplo n.º 6
0
/* connect overlays to the new device, if not already connected. if force
 * selected, connect always. */
void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
{
	int i;
	struct omap_overlay_manager *lcd_mgr;
	struct omap_overlay_manager *tv_mgr;
	struct omap_overlay_manager *lcd2_mgr = NULL;
	struct omap_overlay_manager *mgr = NULL;

	lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD);
	tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV);
	if (cpu_is_omap44xx())
		lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2);

	if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
		if (!lcd2_mgr->device || force) {
			if (lcd2_mgr->device)
				lcd2_mgr->unset_device(lcd2_mgr);
			lcd2_mgr->set_device(lcd2_mgr, dssdev);
			mgr = lcd2_mgr;
		}
	} else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
		&& dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
		if (!lcd_mgr->device || force) {
			if (lcd_mgr->device)
				lcd_mgr->unset_device(lcd_mgr);
			lcd_mgr->set_device(lcd_mgr, dssdev);
			mgr = lcd_mgr;
		}
	}

	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
		|| dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
		if (!tv_mgr->device || force) {
			if (tv_mgr->device)
				tv_mgr->unset_device(tv_mgr);
			tv_mgr->set_device(tv_mgr, dssdev);
			mgr = tv_mgr;
		}
	}

	if (mgr) {
		for (i = 0; i < MAX_DSS_OVERLAYS; i++) {
			struct omap_overlay *ovl;
			ovl = omap_dss_get_overlay(i);
			if (!ovl->manager || force) {
				if (ovl->manager)
					omap_dss_unset_manager(ovl);
				omap_dss_set_manager(ovl, mgr);
			}
		}
	}
}
Exemplo n.º 7
0
/*
 * Connect dssdev to a manager if the manager is free or if force is specified.
 * Connect all overlays to that manager if they are free or if force is
 * specified.
 */
static int dss_init_connections(struct omap_dss_device *dssdev, bool force)
{
	struct omap_dss_output *out;
	struct omap_overlay_manager *mgr;
	int i, r;

	out = omapdss_get_output_from_dssdev(dssdev);

	WARN_ON(dssdev->output);
	WARN_ON(out->device);

	r = omapdss_output_set_device(out, dssdev);
	if (r) {
		DSSERR("failed to connect output to new device\n");
		return r;
	}

	mgr = omap_dss_get_overlay_manager(dssdev->channel);

	if (mgr->output && !force)
		return 0;

	if (mgr->output)
		mgr->unset_output(mgr);

	r = mgr->set_output(mgr, out);
	if (r) {
		DSSERR("failed to connect manager to output of new device\n");

		/* remove the output-device connection we just made */
		omapdss_output_unset_device(out);
		return r;
	}

	for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
		struct omap_overlay *ovl = omap_dss_get_overlay(i);

		if (!ovl->manager || force) {
			if (ovl->manager)
				ovl->unset_manager(ovl);

			r = ovl->set_manager(ovl, mgr);
			if (r) {
				DSSERR("failed to set initial overlay\n");
				return r;
			}
		}
	}

	return 0;
}
/*This one needs to be to set the ovl info to dirty*/
static void dpi_start_auto_update(struct omap_dss_device *dssdev)
{
	int i;

	for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
		struct omap_overlay *ovl;

		ovl = omap_dss_get_overlay(i);

		if (ovl->manager == dssdev->manager)
			ovl->info_dirty = true;
	}
	dssdev->manager->apply(dssdev->manager);
}
Exemplo n.º 9
0
int  omapvout_dss_init(struct omapvout_device *vout, enum omap_plane plane)
{
	struct omap_overlay *ovly;
	int rc = 0;
	int i;
	int cnt;

	if (vout->dss) {
		rc = -EINVAL;
		goto failed;
	}

	vout->dss = kzalloc(sizeof(struct omapvout_dss), GFP_KERNEL);
	if (vout->dss == NULL) {
		rc = -ENOMEM;
		goto failed;
	}

	/* Retrieve the desired DSS overlay object */
	vout->dss->overlay = NULL;
	cnt = omap_dss_get_num_overlays();
	for (i = 0; i < cnt; i++) {
		ovly = omap_dss_get_overlay(i);
		if (ovly->id == plane) {
			vout->dss->overlay = ovly;
			break;
		}
	}

	if (vout->dss->overlay == NULL) {
		DBG("No overlay %d found\n", plane);
		rc = -ENODEV;
		goto failed_mem;
	}

	rc = omapvout_dss_acquire_vrfb(vout);
	if (rc != 0) {
		DBG("VRFB allocation failed\n");
		goto failed_mem;
	}

	vout->dss->vout = vout;

	return rc;

failed_mem:
	kfree(vout->dss);
failed:
	return rc;
}
Exemplo n.º 10
0
static void dump_video_chains(void)
{
	int i;
	DBG("dumping video chains: ");
	for (i = 0; i < omap_dss_get_num_overlays(); i++) {
		struct omap_overlay *ovl = omap_dss_get_overlay(i);
		struct omap_overlay_manager *mgr = ovl->manager;
		struct omap_dss_device *dssdev = mgr ? mgr->device : NULL;
		if (dssdev) {
			DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name, dssdev->name);
		} else if (mgr) {
			DBG("%d: %s -> %s", i, ovl->name, mgr->name);
		} else {
			DBG("%d: %s", i, ovl->name);
		}
	}
}
Exemplo n.º 11
0
/*This one needs to be to set the ovl info to dirty*/
static void dpi_start_auto_update(struct omap_dss_device *dssdev)

{
	int i;
	DSSDBG("starting auto update\n");
	for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
		struct omap_overlay *ovl;
		ovl = omap_dss_get_overlay(i);
		if (!ovl){
			WARN_ON(1);
			continue;
		}
		if (ovl->manager == dssdev->manager)
			ovl->info_dirty = true;
			printk(KERN_ERR "ovl[%d]->manager = %s", i,
				ovl->manager->name);
	}
	if (dssdev->manager)
		dssdev->manager->apply(dssdev->manager);
}
Exemplo n.º 12
0
void dss_read_ovl2mgr_platform_cfg(struct omap_dss_device *dssdev,
			struct omap_ovl2mgr_mapping *overlay_mappings,
							int cnt)
{
	struct omap_overlay_manager *lcd_mgr;
	struct omap_overlay_manager *tv_mgr;
	struct omap_overlay_manager *lcd2_mgr = NULL;
	struct omap_overlay_manager *mgr = NULL;
	int i = 0;

	lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD);
	tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV);
	if (cpu_is_omap44xx())
		lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2);

	for (i = 0; i < cnt; i++) {

		struct omap_overlay *ovl;
		ovl = omap_dss_get_overlay(overlay_mappings[i].overlay_idx);

		switch (overlay_mappings[i].overlay_mgr) {
		case OMAP_DSS_OVL_MGR_LCD:
			mgr = lcd_mgr;
			break;
		case OMAP_DSS_OVL_MGR_TV:
			mgr = tv_mgr;
			break;
		case OMAP_DSS_OVL_MGR_LCD2:
			mgr = lcd2_mgr;
			break;
		default:
			continue;
		}

		if (mgr) {
			if (ovl->manager)
				omap_dss_unset_manager(ovl);
			omap_dss_set_manager(ovl, mgr);
		}
	}
}
Exemplo n.º 13
0
static int omap_modeset_init(struct drm_device *dev)
{
	const struct omap_drm_platform_data *pdata = dev->dev->platform_data;
	struct omap_kms_platform_data *kms_pdata = NULL;
	struct omap_drm_private *priv = dev->dev_private;
	struct omap_dss_device *dssdev = NULL;
	int i, j;
	unsigned int connected_connectors = 0;

	drm_mode_config_init(dev);

	if (pdata && pdata->kms_pdata) {
		kms_pdata = pdata->kms_pdata;

		/* if platform data is provided by the board file, use it to
		 * control which overlays, managers, and devices we own.
		 */
		for (i = 0; i < kms_pdata->mgr_cnt; i++) {
			struct omap_overlay_manager *mgr =
				omap_dss_get_overlay_manager(
						kms_pdata->mgr_ids[i]);
			create_encoder(dev, mgr);
		}

		for (i = 0; i < kms_pdata->dev_cnt; i++) {
			struct omap_dss_device *dssdev =
				omap_dss_find_device(
					(void *)kms_pdata->dev_names[i],
					match_dev_name);
			if (!dssdev) {
				dev_warn(dev->dev, "no such dssdev: %s\n",
						kms_pdata->dev_names[i]);
				continue;
			}
			create_connector(dev, dssdev);
		}

		connected_connectors = detect_connectors(dev);

		j = 0;
		for (i = 0; i < kms_pdata->ovl_cnt; i++) {
			struct omap_overlay *ovl =
				omap_dss_get_overlay(kms_pdata->ovl_ids[i]);
			create_crtc(dev, ovl, &j, connected_connectors);
		}

		for (i = 0; i < kms_pdata->pln_cnt; i++) {
			struct omap_overlay *ovl =
				omap_dss_get_overlay(kms_pdata->pln_ids[i]);
			create_plane(dev, ovl, (1 << priv->num_crtcs) - 1);
		}
	} else {
		/* otherwise just grab up to CONFIG_DRM_OMAP_NUM_CRTCS and try
		 * to make educated guesses about everything else
		 */
		int max_overlays = min(omap_dss_get_num_overlays(), num_crtc);

		for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) {
			create_encoder(dev, omap_dss_get_overlay_manager(i));
		}

		for_each_dss_dev(dssdev) {
			create_connector(dev, dssdev);
		}

		connected_connectors = detect_connectors(dev);

		j = 0;
		for (i = 0; i < max_overlays; i++) {
			create_crtc(dev, omap_dss_get_overlay(i),
					&j, connected_connectors);
		}

		/* use any remaining overlays as drm planes */
		for (; i < omap_dss_get_num_overlays(); i++) {
			struct omap_overlay *ovl = omap_dss_get_overlay(i);
			create_plane(dev, ovl, (1 << priv->num_crtcs) - 1);
		}
	}

	/* for now keep the mapping of CRTCs and encoders static.. */
	for (i = 0; i < priv->num_encoders; i++) {
		struct drm_encoder *encoder = priv->encoders[i];
		struct omap_overlay_manager *mgr =
				omap_encoder_get_manager(encoder);

		encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;

		DBG("%s: possible_crtcs=%08x", mgr->name,
					encoder->possible_crtcs);
	}

	dump_video_chains();

	dev->mode_config.min_width = 32;
	dev->mode_config.min_height = 32;

	/* note: eventually will need some cpu_is_omapXYZ() type stuff here
	 * to fill in these limits properly on different OMAP generations..
	 */
	dev->mode_config.max_width = 2048;
	dev->mode_config.max_height = 2048;

	dev->mode_config.funcs = &omap_mode_config_funcs;

	return 0;
}
Exemplo n.º 14
0
static void OMAPLFBFliepNoLock_HDMI(OMAPLFB_SWAPCHAIN *psSwapChain,
		OMAPLFB_DEVINFO *psDevInfo,
		struct omapfb_info *ofbi,
		struct fb_info *framebuffer,
		unsigned long fb_offset)
{
	struct omap_overlay *ovl_hdmi;
	struct omap_overlay_info info;
	struct omap_overlay *hdmi;
	struct omap_overlay_manager *manager;
	bool overlay_change_requested = false;
	enum omap_dss_overlay_s3d_type  s3d_type_in_video_hdmi = omap_dss_overlay_s3d_none;

	ovl_hdmi = omap_dss_get_overlay(3);
	if(ovl_hdmi->info.enabled)
		s3d_type_in_video_hdmi = ovl_hdmi->info.s3d_type;


	hdmi = psSwapChain->stHdmiTiler.overlay;
	manager = hdmi->manager;
	hdmi->get_overlay_info(hdmi, &info);

	//not good...
	if ( omap_overlay_info_req[hdmi->id].status==2 )
	{

		info.enabled = omap_overlay_info_req[hdmi->id].enabled;
		info.rotation = omap_overlay_info_req[hdmi->id].rotation;
		info.pos_x = omap_overlay_info_req[hdmi->id].pos_x;
		info.pos_y = omap_overlay_info_req[hdmi->id].pos_y;
		info.out_width = omap_overlay_info_req[hdmi->id].out_width;
		info.out_height = omap_overlay_info_req[hdmi->id].out_height;
		info.global_alpha = omap_overlay_info_req[hdmi->id].global_alpha;
		info.zorder = omap_overlay_info_req[hdmi->id].zorder;

		printk("GUI HDMI layer change requested. req_enabled(%d)\n", omap_overlay_info_req[hdmi->id].enabled);
		omap_overlay_info_req[hdmi->id].status = 0;
		overlay_change_requested = true;
	}

	if ( info.enabled )
	{
		mutex_lock(&psSwapChain->stHdmiTiler.lock);
		if ( !psSwapChain->stHdmiTiler.alloc )
		{
//			if ( AllocTilerForHdmi(psSwapChain, psDevInfo) ) {

				ERROR_PRINTK("Tiler memory for HDMI GUI cloning is not allocated\n");
				mutex_unlock(&psSwapChain->stHdmiTiler.lock);
				return;
//			}
		}

		if ( psSwapChain->stHdmiTiler.alloc )	//if Tiler memory is allocated
		{
			unsigned long line_offset;
			unsigned long w, h;
			unsigned long src_stride, dst_stride;
			unsigned long i;
			unsigned char *dst, *src;
			unsigned long pStride;
			u32 j, *src_4, *dst_4, *dst1_4;
			int ch;

			src_stride = psDevInfo->sFBInfo.ulByteStride;
			dst_stride = psSwapChain->stHdmiTiler.vStride;
			line_offset = fb_offset / src_stride;
			h = psDevInfo->sFBInfo.ulHeight;
			w = psDevInfo->sFBInfo.ulWidth;
			pStride = psSwapChain->stHdmiTiler.pStride;

			//Copy
			dst = (unsigned char*)psSwapChain->stHdmiTiler.vAddr +
				(line_offset * dst_stride);

			src = (unsigned char*)framebuffer->screen_base + fb_offset;


			DEBUG_PRINTK("Copy Start h:%d, src:0x%p src_stride:%d, dst:0x%p dst_stride:%d, line offset:%d, pStride:%d\n",
					h, src, src_stride, dst, dst_stride, line_offset, pStride);

			if( psSwapChain->s3d_type==omap_dss_overlay_s3d_side_by_side && s3d_type_in_video_hdmi == omap_dss_overlay_s3d_top_bottom)
			{
				for(j=0; j<h/2; j++)
				{
					src_4  = (u32 *)(src + src_stride*j);
					dst_4   = (u32 *)(dst + dst_stride*2*j);
					dst1_4 = (u32 *)(dst + dst_stride*2*j + w*2);
					for(i=0;i<w/2;i++)
					{
						*dst_4++ = *src_4;
						*dst1_4++ = *src_4++;
						src_4++;
					}
					src_4  = (u32 *)(src + src_stride*j);
					dst_4   = (u32 *)(dst + dst_stride*(2*j+1));
					dst1_4 = (u32 *)(dst + dst_stride*(2*j+1) + w*2);
					for(i=0;i<w/2;i++) {
						*dst_4++ = *src_4;
						*dst1_4++ = *src_4++;
						src_4++;
					}
				}
				info.s3d_type = omap_dss_overlay_s3d_top_bottom;
			}
			else
			{

				if(hdmi_dma.state == HDMI_DMA_DONE)
				{
					ch = hdmi_dma.frame_pos;
					hdmi->get_overlay_info(hdmi, &hdmi_dma.info[ch]);
					hdmi_dma.hdmi = hdmi;

					printk("S:%x\n", psSwapChain->stHdmiTiler.pAddr + (h * pStride * ch));

					omap_set_dma_transfer_params(hdmi_dma.lch, OMAP_DMA_DATA_TYPE_S32,
						src_stride>>2, h, 0, 0, 0);
					omap_set_dma_src_params(hdmi_dma.lch, 0, OMAP_DMA_AMODE_POST_INC,
						framebuffer->fix.smem_start + fb_offset, 1, 1);
					omap_set_dma_dest_params(hdmi_dma.lch, 0, OMAP_DMA_AMODE_DOUBLE_IDX,
						psSwapChain->stHdmiTiler.pAddr + (h * pStride * ch), 1, pStride - src_stride + 1 );
					omap_dma_set_prio_lch(hdmi_dma.lch, DMA_CH_PRIO_HIGH, DMA_CH_PRIO_HIGH);
					omap_set_dma_src_burst_mode(hdmi_dma.lch, OMAP_DMA_DATA_BURST_16);
					omap_set_dma_dest_burst_mode(hdmi_dma.lch, OMAP_DMA_DATA_BURST_16);

					omap_start_dma(hdmi_dma.lch);
					hdmi_dma.state = HDMI_DMA_TRANSFERRING;

					if ( omap_overlay_info_req[hdmi->id].status==2 )
					{
						hdmi_dma.info[ch].enabled = omap_overlay_info_req[hdmi->id].enabled;
						hdmi_dma.info[ch].rotation = omap_overlay_info_req[hdmi->id].rotation;
						hdmi_dma.info[ch].pos_x = omap_overlay_info_req[hdmi->id].pos_x;
						hdmi_dma.info[ch].pos_y = omap_overlay_info_req[hdmi->id].pos_y;
						hdmi_dma.info[ch].out_width = omap_overlay_info_req[hdmi->id].out_width;
						hdmi_dma.info[ch].out_height = omap_overlay_info_req[hdmi->id].out_height;
						hdmi_dma.info[ch].global_alpha = omap_overlay_info_req[hdmi->id].global_alpha;
						hdmi_dma.info[ch].zorder = omap_overlay_info_req[hdmi->id].zorder;
					}
					//fill info

					//@todo not good find another way later
					hdmi_dma.info[ch].color_mode = ofbi->overlays[0]->info.color_mode;
					hdmi_dma.info[ch].paddr = psSwapChain->stHdmiTiler.pAddr + (h * pStride * ch);
					hdmi_dma.info[ch].vaddr = NULL;		//no need
					if ( hdmi_dma.info[ch].rotation==OMAP_DSS_ROT_90 || hdmi_dma.info[ch].rotation==OMAP_DSS_ROT_270 )
					{
						hdmi_dma.info[ch].width = h;
						hdmi_dma.info[ch].height = w;
						hdmi_dma.info[ch].screen_width = h;
					}
					else
					{
						hdmi_dma.info[ch].width =w;
						hdmi_dma.info[ch].height = h;
						hdmi_dma.info[ch].screen_width = w;
					}
					hdmi_dma.info[ch].rotation_type = OMAP_DSS_ROT_TILER;
					hdmi_dma.info[ch].s3d_type = psSwapChain->s3d_type;

					hdmi_dma.curr_frame = hdmi_dma.frame_pos;
					if( ++hdmi_dma.frame_pos >= HDMI_DMA_MAX ) hdmi_dma.frame_pos = 0;

					if( omap_overlay_info_req[hdmi->id].status == 2) {
						omap_overlay_info_req[hdmi->id].status = 0;
					}
				}
				else printk("DOLCOM : DMA busy!!!!!!!!!!!!!!!!!\n");
static void dispc_error_worker(struct work_struct *work)
{
	int i;
	u32 errors;
	unsigned long flags;
	static const unsigned fifo_underflow_bits[] = {
		DISPC_IRQ_GFX_FIFO_UNDERFLOW,
		DISPC_IRQ_VID1_FIFO_UNDERFLOW,
		DISPC_IRQ_VID2_FIFO_UNDERFLOW,
		DISPC_IRQ_VID3_FIFO_UNDERFLOW,
	};

	spin_lock_irqsave(&dispc_compat.irq_lock, flags);
	errors = dispc_compat.error_irqs;
	dispc_compat.error_irqs = 0;
	spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);

	dispc_runtime_get();

	for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
		struct omap_overlay *ovl;
		unsigned bit;

		ovl = omap_dss_get_overlay(i);
		bit = fifo_underflow_bits[i];

		if (bit & errors) {
			DSSERR("FIFO UNDERFLOW on %s, disabling the overlay\n",
					ovl->name);
			dispc_ovl_enable(ovl->id, false);
			dispc_mgr_go(ovl->manager->id);
			msleep(50);
		}
	}

	for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
		struct omap_overlay_manager *mgr;
		unsigned bit;

		mgr = omap_dss_get_overlay_manager(i);
		bit = dispc_mgr_get_sync_lost_irq(i);

		if (bit & errors) {
			int j;

			DSSERR("SYNC_LOST on channel %s, restarting the output "
					"with video overlays disabled\n",
					mgr->name);

			dss_mgr_disable(mgr);

			for (j = 0; j < omap_dss_get_num_overlays(); ++j) {
				struct omap_overlay *ovl;
				ovl = omap_dss_get_overlay(j);

				if (ovl->id != OMAP_DSS_GFX &&
						ovl->manager == mgr)
					ovl->disable(ovl);
			}

			dss_mgr_enable(mgr);
		}
	}

	if (errors & DISPC_IRQ_OCP_ERR) {
		DSSERR("OCP_ERR\n");
		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
			struct omap_overlay_manager *mgr;

			mgr = omap_dss_get_overlay_manager(i);
			dss_mgr_disable(mgr);
		}
	}

	spin_lock_irqsave(&dispc_compat.irq_lock, flags);
	dispc_compat.irq_error_mask |= errors;
	_omap_dispc_set_irqs();
	spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);

	dispc_runtime_put();
}
Exemplo n.º 16
0
static int omap_modeset_init(struct drm_device *dev)
{
	const struct omap_gpu_platform_data *pdata = dev->dev->platform_data;
	struct omap_gpu_private *priv = dev->dev_private;
	struct omap_dss_device *dssdev = NULL;
	int i, j;
	unsigned int connected_connectors = 0;

	/* create encoders for each manager */
	int create_encoder(int i) {
		struct omap_overlay_manager *mgr = omap_dss_get_overlay_manager(i);
		struct drm_encoder *encoder = omap_encoder_init(dev, mgr);

		if (!encoder) {
			dev_err(dev->dev, "could not create encoder\n");
			return -ENOMEM;
		}

		priv->encoders[priv->num_encoders++] = encoder;

		return 0;
	}

	/* create connectors for each display device */
	int create_connector(struct omap_dss_device *dssdev) {
		static struct notifier_block *notifier;
		struct drm_connector *connector;

		if (!dssdev->driver) {
			dev_warn(dev->dev, "%s has no driver.. skipping it\n",
					dssdev->name);
			return 0;
		}

		if (!(dssdev->driver->get_timings || dssdev->driver->get_edid)) {
			dev_warn(dev->dev, "%s driver does not support "
					"get_timings or get_edid.. skipping it!\n",
					dssdev->name);
			return 0;
		}

		connector = omap_connector_init(dev,
				get_connector_type(dssdev->type), dssdev);

		if (!connector) {
			dev_err(dev->dev, "could not create connector\n");
			return -ENOMEM;
		}

		/* track what is already connected.. rather than looping thru all
		 * connectors twice later, first for connected then for remainder
		 * (which could be a race condition if connected status changes)
		 */
		if (omap_connector_detect (connector) == connector_status_connected) {
			connected_connectors |= (1 << priv->num_connectors);
		}

		priv->connectors[priv->num_connectors++] = connector;

		notifier = kzalloc(sizeof(struct notifier_block), GFP_KERNEL);
		notifier->notifier_call = omap_gpu_notifier;
		omap_dss_add_notify(dssdev, notifier);

		for (j = 0; j < priv->num_encoders; j++) {
			struct omap_overlay_manager *mgr =
					omap_encoder_get_manager(priv->encoders[j]);
			if (mgr->device == dssdev) {
				drm_mode_connector_attach_encoder(connector,
						priv->encoders[j]);
			}
		}

		return 0;
	}

	/* create up to max_overlays CRTCs mapping to overlays.. by default,
	 * connect the overlays to different managers/encoders, giving priority
	 * to encoders connected to connectors with a detected connection
	 */
	int create_crtc(int i) {
		struct omap_overlay *ovl = omap_dss_get_overlay(i);
		struct omap_overlay_manager *mgr = NULL;
		struct drm_crtc *crtc;

		if (ovl->manager) {
			DBG("disconnecting %s from %s", ovl->name, ovl->manager->name);
			ovl->unset_manager(ovl);
		}

		/* find next best connector... ones with detected connection first
		 */
		while (j < priv->num_connectors && !mgr) {
			if (connected_connectors & (1 << j)) {
				struct drm_encoder * encoder =
						omap_connector_attached_encoder (priv->connectors[j]);
				if (encoder) {
					mgr = omap_encoder_get_manager (encoder);
				}
			}
			j++;
		}

		/* if we couldn't find another connected connector, lets start looking
		 * at the unconnected connectors:
		 */
		while (j < 2 * priv->num_connectors && !mgr) {
			int idx = j - priv->num_connectors;
			if (!(connected_connectors & (1 << idx))) {
				struct drm_encoder * encoder =
						omap_connector_attached_encoder (priv->connectors[idx]);
				if (encoder) {
					mgr = omap_encoder_get_manager (encoder);
				}
			}
			j++;
		}

		if (mgr) {
			DBG("connecting %s to %s", ovl->name, mgr->name);
			ovl->set_manager(ovl, mgr);
		}

		crtc = omap_crtc_init(dev, ovl);

		if (!crtc) {
			dev_err(dev->dev, "could not create CRTC\n");
			return -ENOMEM;
		}

		priv->crtcs[priv->num_crtcs++] = crtc;

		return 0;
	}

	drm_mode_config_init(dev);

	if (pdata) {
		/* if platform data is provided by the board file, use it to control
		 * which overlays, managers, and devices we own.
		 */
		for (i = 0; i < pdata->mgr_cnt; i++) {
			if (create_encoder(pdata->mgr_ids[i])) {
				goto fail;
			}
		}

		for (i = 0; i < pdata->dev_cnt; i++) {
			int m(struct omap_dss_device *dssdev, void *data) {
				return ! strcmp(dssdev->name, data);
			}
			struct omap_dss_device *dssdev =
					omap_dss_find_device((void *)pdata->dev_names[i], m);
			if (!dssdev) {
				dev_warn(dev->dev, "no such dssdev: %s\n",
						pdata->dev_names[i]);
				continue;
			}
			if (create_connector(dssdev)) {
				goto fail;
			}
		}

		j = 0;
		for (i = 0; i < pdata->ovl_cnt; i++) {
			if (create_crtc(pdata->ovl_ids[i])) {
				goto fail;
			}
		}
	} else {