예제 #1
0
static void sh_mobile_fb_reconfig(struct fb_info *info)
{
	struct sh_mobile_lcdc_chan *ch = info->par;
	struct fb_videomode mode1, mode2;
	struct fb_event event;
	int evnt = FB_EVENT_MODE_CHANGE_ALL;

	if (ch->use_count > 1 || (ch->use_count == 1 && !info->fbcon_par))
		/* More framebuffer users are active */
		return;

	fb_var_to_videomode(&mode1, &ch->display_var);
	fb_var_to_videomode(&mode2, &info->var);

	if (fb_mode_is_equal(&mode1, &mode2))
		return;

	/* Display has been re-plugged, framebuffer is free now, reconfigure */
	if (fb_set_var(info, &ch->display_var) < 0)
		/* Couldn't reconfigure, hopefully, can continue as before */
		return;

	info->fix.line_length = mode1.xres * (ch->cfg.bpp / 8);

	/*
	 * fb_set_var() calls the notifier change internally, only if
	 * FBINFO_MISC_USEREVENT flag is set. Since we do not want to fake a
	 * user event, we have to call the chain ourselves.
	 */
	event.info = info;
	event.data = &mode1;
	fb_notifier_call_chain(evnt, &event);
}
예제 #2
0
static void start_vsync_boost(struct tb_private_info *info)
{
	int ret = 0;

#ifdef CONFIG_FB_DYNAMIC_FREQ
	do {
		struct fb_event event;
		event.data = info;
		ret = fb_notifier_call_chain(FB_EVENT_MODE_PAN, &event);
	} while(0);
#endif
}
예제 #3
0
static int s5p_dp_notify(struct notifier_block *nb,
	unsigned long action, void *data)
{
	struct s5p_dp_device *dp;
	int ret = 0;
	ktime_t start;
#if defined(CONFIG_V1A) || defined(CONFIG_V2A) || defined(CONFIG_CHAGALL)
	struct fb_event event;
#endif
	dp = container_of(nb, struct s5p_dp_device, notifier);

	switch (action) {
		case FB_EVENT_PSR_ENTER:
#if defined(CONFIG_V1A) || defined(CONFIG_V2A) || defined(CONFIG_CHAGALL)
			fb_notifier_call_chain(FB_EVENT_PSR_WACOM_CHECK, &event);
#endif
			dev_dbg(dp->dev, "FB_EVENT_PSR_ENTER occurs!\n");

			start = ktime_get();
			ret = s5p_dp_psr_enter(dp);
			dev_info(dp->dev,"FB_EVENT_PSR_ENTER time = %lld us\n",
					ktime_us_delta(ktime_get(), start));
			break;
		case FB_EVENT_PSR_PRE_ENTRY:
			dev_dbg(dp->dev, "FB_EVENT_PRE_ENTRY occurs!\n");

			ret = s5p_dp_psr_pre_entry(dp);
			break;
		case FB_EVENT_PSR_EXIT:
			dev_dbg(dp->dev, "FB_EVENT_PSR_EXIT occurs!\n");

			dp->psr_exit_state = PSR_PRE_EXIT;
			start = ktime_get();
			ret = s5p_dp_psr_exit(dp);
			dev_info(dp->dev,"FB_EVENT_PSR_EXIT time = %lld us\n",
					ktime_us_delta(ktime_get(), start));
			break;
	}
	return ret;
}
static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
{
	int ret;
	int i;
	struct vga_switcheroo_client *active = NULL;

	for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
		if (vgasr_priv.clients[i].active == true) {
			active = &vgasr_priv.clients[i];
			break;
		}
	}
	if (!active)
		return 0;

	active->active = false;

	if (new_client->fb_info) {
		struct fb_event event;
		event.info = new_client->fb_info;
		fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event);
	}

	ret = vgasr_priv.handler->switchto(new_client->id);
	if (ret)
		return ret;

	if (new_client->reprobe)
		new_client->reprobe(new_client->pdev);

	if (active->pwr_state == VGA_SWITCHEROO_ON)
		vga_switchoff(active);

	new_client->active = true;
	return 0;
}
예제 #5
0
static int s5p_dp_psr_enter(struct s5p_dp_device *dp)
{
	struct platform_device *pdev;
	struct s5p_dp_platdata *pdata;
	int timeout_loop = 0;
	struct fb_event event;
	int ret = 0;
	u8 data;

	pdev = to_platform_device(dp->dev);
	pdata = pdev->dev.platform_data;

	mutex_lock(&dp->lock);
	dev_dbg(dp->dev, "%s +\n", __func__);

	if (dp->psr_enter_state == PSR_ENTER_DONE) {
		dev_info(dp->dev, "%s: Already edP PSR_ENTER state\n", __func__);
		goto err_exit;
	}

	if (dp->psr_exit_state == PSR_PRE_EXIT) {
		dev_info(dp->dev, "%s: edP does not need to PSR_ENTER\n", __func__);
		goto err_exit;
	}

	dp->psr_enter_state = PSR_PRE_ENTER;
	s5p_dp_enable_psr(dp);

	for (;;) {
		timeout_loop++;
		if (s5p_dp_get_psr_status(dp) == PSR_STATUS_ACTIVE)
			break;
		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
			dev_err(dp->dev, "DP: Timeout of PSR active\n");
			ret = -ETIMEDOUT;
			dp->psr_enter_state = PSR_NONE;
			dp->psr_error_count++;
			goto err_exit;
		}
		mdelay(1);
	}

	mdelay(2);
	dev_dbg(dp->dev, "PSR ENTER DP timeout_loop: %d\n", timeout_loop);

	s5p_dp_read_byte_from_dpcd(dp, DPCD_ADDR_SINK_PSR_STATUS, &data);
	if (data == 0)
		dev_info(dp->dev, "%s: SINK_PSR_STATUS = 0x%02X\n",
			__func__, data);

	s5p_dp_set_analog_power_down(dp, ANALOG_TOTAL, 1);

	clk_disable(dp->clock);

	fb_notifier_call_chain(FB_EVENT_PSR_DONE, &event);
	dp->psr_enter_state = PSR_ENTER_DONE;

err_exit:
	dev_dbg(dp->dev, "%s -\n", __func__);
	mutex_unlock(&dp->lock);
	return ret;
}
예제 #6
0
static void vigs_crtc_dpms(struct drm_crtc *crtc, int mode)
{
    struct vigs_crtc *vigs_crtc = crtc_to_vigs_crtc(crtc);
    struct vigs_device *vigs_dev = crtc->dev->dev_private;
    int blank, i;
    struct fb_event event;

    DRM_DEBUG_KMS("enter: fb_blank = %d, mode = %d\n",
                  vigs_crtc->in_fb_blank,
                  mode);

    if (vigs_crtc->in_fb_blank) {
        return;
    }

    switch (mode) {
    case DRM_MODE_DPMS_ON:
        blank = FB_BLANK_UNBLANK;
        break;
    case DRM_MODE_DPMS_STANDBY:
        blank = FB_BLANK_NORMAL;
        break;
    case DRM_MODE_DPMS_SUSPEND:
        blank = FB_BLANK_VSYNC_SUSPEND;
        break;
    case DRM_MODE_DPMS_OFF:
        blank = FB_BLANK_POWERDOWN;
        break;
    default:
        DRM_ERROR("unspecified mode %d\n", mode);
        return;
    }

    event.info = vigs_dev->fbdev->base.fbdev;
    event.data = &blank;

    /*
     * We can't just 'console_lock' here, since
     * this may result in deadlock:
     * fb func:
     * console_lock();
     * mutex_lock(&dev->mode_config.mutex);
     * DRM func:
     * mutex_lock(&dev->mode_config.mutex);
     * console_lock();
     *
     * So we just try to acquire it for 5 times with a delay
     * and then just skip.
     *
     * This code is here only because pm is currently done via
     * backlight which is bad, we need to make proper pm via
     * kernel support.
     */
    for (i = 0; i < 5; ++i) {
        if (console_trylock()) {
            fb_notifier_call_chain(FB_EVENT_BLANK, &event);
            console_unlock();
            return;
        }
        msleep(100);
        DRM_ERROR("unable to lock console, trying again\n");
    }

    DRM_ERROR("unable to lock console, skipping fb call chain\n");
}