コード例 #1
0
int psb_update_guard(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct dpst_guardband *input = (struct dpst_guardband *)data;
	struct mdfld_dsi_config *dsi_config = NULL;
	struct mdfld_dsi_hw_context *ctx = NULL;
	struct dpst_guardband reg_data;

	if (!dev_priv)
		return 0;
	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;
	ctx = &dsi_config->dsi_hw_context;

	if (!ospm_power_using_hw_begin
	    (OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON))
		return 0;

	mdfld_dsi_dsr_forbid(dsi_config);

	reg_data.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
	reg_data.guardband = input->guardband;
	reg_data.guardband_interrupt_delay = input->guardband_interrupt_delay;

	PSB_WVDC32(reg_data.data, HISTOGRAM_INT_CONTROL);
	ctx->histogram_intr_ctrl = reg_data.data;

	mdfld_dsi_dsr_allow(dsi_config);

	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	return 0;
}
コード例 #2
0
/**
 * Exit from DSR
 */
void mdfld_dsi_dpi_exit_idle(struct drm_device *dev,
                             u32 update_src,
                             void *p_surfaceAddr,
                             bool check_hw_on_only)
{
    struct drm_psb_private * dev_priv = dev->dev_private;
    unsigned long irqflags;

    /* PSB_DEBUG_ENTRY("\n"); */

    if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
                                   OSPM_UHB_ONLY_IF_ON)) {
        DRM_ERROR("display island is in off state\n");
        return;
    }

    spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
    /* update the surface base address. */
    if (p_surfaceAddr) {
        REG_WRITE(DSPASURF, *((u32 *)p_surfaceAddr));
#if defined(CONFIG_MDFD_DUAL_MIPI)
        REG_WRITE(DSPCSURF, *((u32 *)p_surfaceAddr));
#endif
    }

    mid_enable_pipe_event(dev_priv, 0);
    psb_enable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);

    spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
    ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
}
コード例 #3
0
static
void mdfld_dsi_dpi_commit(struct drm_encoder *encoder)
{
    struct mdfld_dsi_encoder *dsi_encoder;
    struct mdfld_dsi_dpi_output *dpi_output;
    struct mdfld_dsi_hw_context *ctx;
    struct mdfld_dsi_config *dsi_config;
    struct drm_device *dev;
    u32 temp_val = 0;

    PSB_DEBUG_ENTRY("\n");

    dsi_encoder = MDFLD_DSI_ENCODER(encoder);
    dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
    dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
    dev = dsi_config->dev;
    ctx = &dsi_config->dsi_hw_context;

    if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON))
        return;
    temp_val = REG_READ(PIPEACONF);
    temp_val &= ~(BIT27 | BIT28);
    /* Setup pipe configuration for different panels*/
    REG_WRITE(PIPEACONF, temp_val | (ctx->pipeconf & (BIT27 | BIT28)));
    ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

    /*Everything is ready, commit DSI hw context to HW*/
    __mdfld_dsi_dpi_set_power(encoder, true);
    dpi_output->first_boot = 0;
}
コード例 #4
0
static void dpst_restore_gamma_settings(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct mdfld_dsi_config *dsi_config;
	struct mdfld_dsi_hw_context *ctx;
	struct drm_connector *connector;
	struct drm_crtc *crtc;
	struct psb_intel_crtc *psb_intel_crtc;
	int i = 0;

	if (!dev_priv)
		return;

	connector = dev_priv->dpst_lvds_connector;
	dsi_config = dev_priv->dsi_configs[0];
	ctx = &dsi_config->dsi_hw_context;

	crtc = connector->encoder->crtc;
	psb_intel_crtc = to_psb_intel_crtc(crtc);

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
				OSPM_UHB_FORCE_POWER_ON))
		return;
	mdfld_dsi_dsr_forbid(dsi_config);

	for (i = 0; i < 256; i++) {
		ctx->palette[i] = lut_adj[i];
		REG_WRITE((PALETTE_A + 4 * i), lut_adj[i]);
	}

	mdfld_dsi_dsr_allow(dsi_config);
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
}
コード例 #5
0
inline int had_get_hwstate(struct snd_intelhad *intelhaddata)
{
	/* Check for device presence -SW state */
	if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) {
		pr_debug("%s:Device not connected:%d\n", __func__,
				intelhaddata->drv_status);
		return -ENODEV;
	}

	/* Check for device presence -HW state */
	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
				OSPM_UHB_ONLY_IF_ON)) {
		pr_err("%s:Device not connected\n", __func__);
		dump_stack();
		/* HOT_UNPLUG event can be sent to
		 * maintain correct state within HAD
		 * had_event_handler(HAD_EVENT_HOT_UNPLUG, intelhaddata);
		 * Drop all acuired locks before executing this.
		 */
		return -ENODEV;
	}

	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
	return 0;
}
コード例 #6
0
IMG_BOOL  MRSTLFBFlipToSurface(MRSTLFB_DEVINFO *psDevInfo,
		unsigned long uiAddr)
{
    int dspbase = (psDevInfo->ui32MainPipe == 0 ? DSPABASE : DSPBBASE);
    int dspsurf = (psDevInfo->ui32MainPipe == 0 ? DSPASURF : DSPBSURF);
    struct drm_device * dev = psDevInfo->psDrmDevice;
    struct drm_psb_private *dev_priv =
        (struct drm_psb_private *) psDevInfo->psDrmDevice->dev_private;
    MRSTLFB_SWAPCHAIN *psCurrentSwapChain = psDevInfo->psCurrentSwapChain;

    if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, false))
    {
        if (IS_MRST(dev)) {
            MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr);
        } else if (IS_MDFLD(dev)) {
		if (psCurrentSwapChain != NULL) {
			if (psCurrentSwapChain->ui32SwapChainPropertyFlag
					& PVRSRV_SWAPCHAIN_ATTACHED_PLANE_A) {
				dspsurf = DSPASURF;
				MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr);
				if (dev_priv->b_async_flip_enable &&
						dev_priv->async_flip_update_fb)
					if (dev_priv->async_flip_update_fb(
						dev, 0)	== IMG_FALSE)
						return IMG_FALSE;
			}
#if defined(CONFIG_MDFD_DUAL_MIPI)
			if (psCurrentSwapChain->ui32SwapChainPropertyFlag
					& PVRSRV_SWAPCHAIN_ATTACHED_PLANE_C) {
				dspsurf = DSPCSURF;
				MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr);
				if (dev_priv->b_async_flip_enable &&
						 dev_priv->async_flip_update_fb)
					if (dev_priv->async_flip_update_fb(
						 dev, 2) == IMG_FALSE)
						return IMG_FALSE;
			}
#endif
#ifdef CONFIG_MDFD_HDMI
			/* To avoid Plane B still fetches data from original frame
			 * buffer. */
			if (psCurrentSwapChain->ui32SwapChainPropertyFlag
					& PVRSRV_SWAPCHAIN_ATTACHED_PLANE_B) {
				dspsurf = DSPBSURF;
				MRSTLFBVSyncWriteReg(psDevInfo, dspsurf, uiAddr);
			}
#endif
		} else {
			printk(KERN_WARNING "Current Swapchain is null, no attached plane info\
				 available, omit address update\n");
			if (drm_psb_debug & PSB_D_GENERAL)
				dump_stack();
		}
        } else {
            MRSTLFBVSyncWriteReg(psDevInfo, dspbase, uiAddr);
        }
        ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
    }
コード例 #7
0
/* SH TODO This doesn't work yet. */
int psb_diet_enable(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct mdfld_dsi_config *dsi_config = NULL;
	struct mdfld_dsi_hw_context *ctx = NULL;
	uint32_t *arg = data;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	u32 i;
	int dpst3_bin_threshold_count = 1;
	int dpst_hsv_multiplier = 2;
	uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL;
	uint32_t iebdr_reg = HISTOGRAM_BIN_DATA;
	int dpst3_bin_count = 32;

	if (!dev_priv)
		return 0;
	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;
	ctx = &dsi_config->dsi_hw_context;

	if (!ospm_power_using_hw_begin
	    (OSPM_DISPLAY_ISLAND, OSPM_UHB_ONLY_IF_ON))
		return 0;

	mdfld_dsi_dsr_forbid(dsi_config);

	if (data) {
		ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
		ie_hist_cont_reg.bin_reg_func_select =
		    dpst3_bin_threshold_count;
		ie_hist_cont_reg.bin_reg_index = 0;

		PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);

		for (i = 0; i < dpst3_bin_count; i++)
			PSB_WVDC32(arg[i], iebdr_reg);
		ctx->aimg_enhance_bin = PSB_RVDC32(iebdr_reg);

		ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
		ie_hist_cont_reg.ie_mode_table_enabled = 1;
		ie_hist_cont_reg.alt_enhancement_mode = dpst_hsv_multiplier;

		PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
		ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;
	} else {
		ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
		ie_hist_cont_reg.ie_mode_table_enabled = 0;

		PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
		ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;
	}

	mdfld_dsi_dsr_allow(dsi_config);
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	return 0;
}
コード例 #8
0
static int psb_hist_status(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct drm_psb_hist_status_arg *hist_status = data;
	uint32_t *arg = hist_status->buf;
	struct mdfld_dsi_config *dsi_config = NULL;
	u32 iedbr_reg_data = 0;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	u32 i;
	int dpst3_bin_threshold_count = 0;
	uint32_t blm_hist_ctl = HISTOGRAM_LOGIC_CONTROL;
	uint32_t iebdr_reg = HISTOGRAM_BIN_DATA;
	uint32_t segvalue_max_22_bit = 0x3fffff;
	uint32_t iedbr_busy_bit = 0x80000000;
	int dpst3_bin_count = 32;

	if (!dev_priv)
		return 0;
	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;

	if (!ospm_power_using_hw_begin
	    (OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) {
		return 0;
	}
	mdfld_dsi_dsr_forbid(dsi_config);

	ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
	ie_hist_cont_reg.bin_reg_func_select = dpst3_bin_threshold_count;
	ie_hist_cont_reg.bin_reg_index = 0;

	PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);

	for (i = 0; i < dpst3_bin_count; i++) {
		iedbr_reg_data = PSB_RVDC32(iebdr_reg);

		if (!(iedbr_reg_data & iedbr_busy_bit)) {
			arg[i] = iedbr_reg_data & segvalue_max_22_bit;
		} else {
			i = 0;
			ie_hist_cont_reg.data = PSB_RVDC32(blm_hist_ctl);
			ie_hist_cont_reg.bin_reg_index = 0;
			PSB_WVDC32(ie_hist_cont_reg.data, blm_hist_ctl);
		}
	}
	mdfld_dsi_dsr_allow(dsi_config);

	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	return 0;
}
コード例 #9
0
void gl3_disable(void)
{
	struct drm_psb_private *dev_priv =
		    (struct drm_psb_private *) gpDrmDevice->dev_private;

	PSB_DEBUG_ENTRY("gl3_disable called on platform %x\n",	dev_priv->platform_rev_id);
	if (!ospm_power_using_hw_begin(OSPM_GRAPHICS_ISLAND, true))
		return;
	MDFLD_GL3_WRITE(MDFLD_GL3_DISABLE_CACHE, MDFLD_GL3_CONTROL);
	PSB_DEBUG_GENERAL("gl3 cache disabled with mask %x\n",
			MDFLD_GL3_DISABLE_CACHE);
	ospm_power_using_hw_end(OSPM_GRAPHICS_ISLAND);
}
コード例 #10
0
void gl3_reset(void)
{
	struct drm_psb_private *dev_priv =
		    (struct drm_psb_private *) gpDrmDevice->dev_private;

	PSB_DEBUG_ENTRY("gl3_reset called on platform %x\n",	dev_priv->platform_rev_id);
	if (!ospm_power_using_hw_begin(OSPM_GRAPHICS_ISLAND, true))
		return;
	// Reset the cache
	MDFLD_GL3_WRITE(MDFLD_GL3_SOFT_RESET_ENABLE, MDFLD_GL3_G_CONTROL);
	PSB_DEBUG_GENERAL("gl3 cache soft reset with mas %x\n",
			MDFLD_GL3_SOFT_RESET_ENABLE);
	ospm_power_using_hw_end(OSPM_GRAPHICS_ISLAND);
}
コード例 #11
0
int mdfld_panel_generic_dsi_dbi_power_on(struct drm_encoder *encoder)
{
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output *dbi_output =
		MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	struct mdfld_dsi_config *dsi_config =
		mdfld_dsi_encoder_get_config(dsi_encoder);
	struct panel_funcs *p_funcs = dbi_output->p_funcs;
	struct mdfld_dsi_hw_registers *regs = NULL;
	struct mdfld_dsi_hw_context *ctx = NULL;
	struct drm_device *dev = encoder->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	int err = 0;

	if (!dev_priv->dsi_init_done)
		return 0;

	if (!dsi_config)
		return -EINVAL;

	regs = &dsi_config->regs;
	ctx = &dsi_config->dsi_hw_context;

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
					OSPM_UHB_FORCE_POWER_ON))
		return -EAGAIN;


	/*
	 * Different panel may have different ways to have
	 * panel turned on. Support it!
	 */
	if (p_funcs && p_funcs->power_on) {
		p_funcs->dsi_controller_init(dsi_config,
				dsi_config->pipe, true);

		if (p_funcs->power_on(dsi_config)) {
			DRM_ERROR("Failed to power on panel\n");
			err = -EAGAIN;
			goto power_on_err;
		}
	}

power_on_err:
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
	return err;
}
コード例 #12
0
int mdfld_panel_generic_dsi_dbi_power_off(struct drm_encoder *encoder)
{
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output *dbi_output =
		MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	struct mdfld_dsi_config *dsi_config =
		mdfld_dsi_encoder_get_config(dsi_encoder);
	struct panel_funcs *p_funcs = dbi_output->p_funcs;
	struct mdfld_dsi_hw_context *ctx;
	struct drm_device *dev = encoder->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	int err = 0;

	if (!dev_priv->dsi_init_done)
		return 0;

	if (!dsi_config)
		return -EINVAL;

	ctx = &dsi_config->dsi_hw_context;

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
					OSPM_UHB_FORCE_POWER_ON))
		return -EAGAIN;

	ctx->lastbrightnesslevel = psb_brightness;

	/*
	 * Different panel may have different ways to have
	 * panel turned off. Support it!
	 */
	if (p_funcs && p_funcs->power_off) {
		if (p_funcs->power_off(dsi_config)) {
			DRM_ERROR("Failed to power off panel\n");
			err = -EAGAIN;
			goto power_off_err;
		}
	}

power_off_err:
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
	return err;
}
コード例 #13
0
static
int mdfld_dsi_pr2_detect(struct mdfld_dsi_config *dsi_config)
{
	int status;
	struct drm_device *dev = dsi_config->dev;
	struct mdfld_dsi_hw_registers *regs = &dsi_config->regs;
	u32 dpll_val, device_ready_val;
	int pipe = dsi_config->pipe;

	PSB_DEBUG_ENTRY("\n");

	if (pipe == 0) {
		/*
		 * FIXME: WA to detect the panel connection status, and need to
		 * implement detection feature with get_power_mode DSI command.
		 */
		if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
					OSPM_UHB_FORCE_POWER_ON)) {
			DRM_ERROR("hw begin failed\n");
			return -EAGAIN;
		}

		dpll_val = REG_READ(regs->dpll_reg);
		device_ready_val = REG_READ(regs->device_ready_reg);
		if ((device_ready_val & DSI_DEVICE_READY) &&
		    (dpll_val & DPLL_VCO_ENABLE)) {
			dsi_config->dsi_hw_context.panel_on = true;
		} else {
			dsi_config->dsi_hw_context.panel_on = false;
			DRM_INFO("%s: panel is not detected!\n", __func__);
		}

		status = MDFLD_DSI_PANEL_CONNECTED;

		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
	} else {
		DRM_INFO("%s: do NOT support dual panel\n", __func__);
		status = MDFLD_DSI_PANEL_DISCONNECTED;
	}

	return status;
}
コード例 #14
0
PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32			ui32DeviceIndex,
									 PVRSRV_DEV_POWER_STATE	eNewPowerState,
									 PVRSRV_DEV_POWER_STATE	eCurrentPowerState)
{
	if ((eNewPowerState != eCurrentPowerState) &&
	    (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF))
	{
		if (ui32DeviceIndex == gui32SGXDeviceID)
		{
			PVR_DPF((PVR_DBG_MESSAGE,"SysDevicePrePowerState: Restore SGX power"));
#if defined(SUPPORT_DRI_DRM_EXT)
			ospm_power_using_hw_begin(OSPM_GRAPHICS_ISLAND, true);
#endif

		}
		else if (ui32DeviceIndex == gui32MRSTMSVDXDeviceID)
		{
			PVR_DPF((PVR_DBG_MESSAGE,"SysDevicePrePowerState: Restore MSVDX power"));
			if (ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
				ospm_power_island_up(OSPM_VIDEO_DEC_ISLAND);
			} else {
				ospm_power_island_up(OSPM_DISPLAY_ISLAND);
				ospm_power_island_up(OSPM_VIDEO_DEC_ISLAND);
				ospm_power_island_down(OSPM_DISPLAY_ISLAND);
			}
		}
		else if (ui32DeviceIndex == gui32MRSTTOPAZDeviceID)
		{
			PVR_DPF((PVR_DBG_MESSAGE,"SysDevicePrePowerState: Restore TOPAZ power"));
			if (ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
				ospm_power_island_up(OSPM_VIDEO_ENC_ISLAND);
			} else {
				ospm_power_island_up(OSPM_DISPLAY_ISLAND);
				ospm_power_island_up(OSPM_VIDEO_ENC_ISLAND);
				ospm_power_island_down(OSPM_DISPLAY_ISLAND);
			}
		}
	}

	return PVRSRV_OK;
}
コード例 #15
0
void mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
{
    struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
    struct mdfld_dsi_config *dsi_config =
        mdfld_dsi_encoder_get_config(dsi_encoder);
    int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
    struct drm_device *dev = dsi_config->dev;
    struct drm_psb_private *dev_priv = dev->dev_private;
    struct mdfld_dsi_dpi_output *dpi_output = NULL;
    u32 mipi_reg = MIPI;
    u32 pipeconf_reg = PIPEACONF;

    PSB_DEBUG_ENTRY("set power %s on pipe %d\n", on ? "On" : "Off", pipe);

    dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);

    if (pipe)
        if (!(dev_priv->panel_desc & DISPLAY_B) ||
                !(dev_priv->panel_desc & DISPLAY_C))
            return;

    if (pipe) {
        mipi_reg = MIPI_C;
        pipeconf_reg = PIPECCONF;
    }

    /*start up display island if it was shutdown*/
    if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
                                   OSPM_UHB_FORCE_POWER_ON))
        return;

    /**
     * if TMD panel call new power on/off sequences instead.
     * NOTE: refine TOSHIBA panel code later
     */
    __mdfld_dsi_dpi_set_power(encoder, on);

    ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
}
コード例 #16
0
int psb_dpst_mode(struct drm_device *dev, void *data)
{
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct mdfld_dsi_config *dsi_config = NULL;
	uint32_t *arg = data;
	uint32_t x = 0;
	uint32_t y = 0;
	uint32_t reg;

	if (!dev_priv)
		return 0;

	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;
	mdfld_dsi_dsr_forbid(dsi_config);

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
				OSPM_UHB_ONLY_IF_ON))
		return 0;

	reg = PSB_RVDC32(PIPEASRC);

	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	mdfld_dsi_dsr_allow(dsi_config);
	/* horizontal is the left 16 bits */
	x = reg >> 16;
	/* vertical is the right 16 bits */
	y = reg & 0x0000ffff;

	/* the values are the image size minus one */
	x += 1;
	y += 1;

	*arg = (x << 16) | y;

	return 0;
}
コード例 #17
0
ファイル: dispmgrnl.c プロジェクト: nel82/android_zenfone4_JB
/* this function is only called by dpms on or late resume function */
void dpstmgr_reg_restore_locked(struct mdfld_dsi_config *dsi_config)
{
	struct mdfld_dsi_hw_context *ctx = NULL;
	struct drm_psb_private *dev_priv = NULL;
	struct mdfld_dsi_hw_registers *regs = NULL;

	if (!dsi_config || !dsi_config->dev)
		return;
	ctx = &dsi_config->dsi_hw_context;
	regs = &dsi_config->regs;
	dev_priv = dsi_config->dev->dev_private;

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
				OSPM_UHB_ONLY_IF_ON))
			return;

	PSB_WVDC32(ctx->histogram_intr_ctrl, regs->histogram_intr_ctrl_reg);
	PSB_WVDC32(ctx->histogram_logic_ctrl, regs->histogram_logic_ctrl_reg);
	PSB_WVDC32(ctx->aimg_enhance_bin, regs->aimg_enhance_bin_reg);
	PSB_WVDC32(ctx->lvds_port_ctrl, regs->lvds_port_ctrl_reg);

	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
}
コード例 #18
0
int mdfld_panel_generic_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
{
	int ret = 0;
	struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output *dbi_output =
		MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	struct panel_funcs *p_funcs = dbi_output->p_funcs;
	struct mdfld_dsi_connector *dsi_connector =
		mdfld_dsi_encoder_get_connector(dsi_encoder);
	struct mdfld_dsi_config *dsi_config =
		mdfld_dsi_encoder_get_config(dsi_encoder);
	struct drm_device *dev = encoder->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	u32 reg_offset = 0;
	int pipe = (dbi_output->channel_num == 0) ? 0 : 2;

	PSB_DEBUG_ENTRY("pipe %d : %s, panel on: %s\n", pipe, on ? "On" : "Off",
			dbi_output->dbi_panel_on ? "True" : "False");

	if (pipe == 2) {
		if (on)
			dev_priv->dual_mipi = true;
		else
			dev_priv->dual_mipi = false;

		reg_offset = MIPIC_REG_OFFSET;
	} else {
		if (!on)
			dev_priv->dual_mipi = false;
	}

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
				OSPM_UHB_FORCE_POWER_ON)) {
		DRM_ERROR("hw begin failed\n");
		return -EAGAIN;
	}

	mutex_lock(&dsi_config->context_lock);

	if (on) {
		if (dbi_output->dbi_panel_on)
			goto out_err;

		ret = mdfld_panel_generic_dsi_dbi_power_on(encoder);
		if (ret) {
			DRM_ERROR("power on error\n");
			goto out_err;
		}

		dbi_output->dbi_panel_on = true;

		if (pipe == 2)
			dev_priv->dbi_panel_on2 = true;
		else
			dev_priv->dbi_panel_on = true;

		if (dev_priv->platform_rev_id != MDFLD_PNW_A0)
			mdfld_enable_te(dev, pipe);

		/* wake up error detector if ESD enabled */
		if (p_funcs->esd_detection)
			mdfld_dsi_error_detector_wakeup(dsi_connector);
		else
			PSB_DEBUG_ENTRY("ESD detection disabled\n");

		dsi_config->dsi_hw_context.panel_on = 1;
	} else {
		if (!dbi_output->dbi_panel_on && !dbi_output->first_boot)
			goto out_err;

		dbi_output->dbi_panel_on = false;
		dbi_output->first_boot = false;

		if (pipe == 2)
			dev_priv->dbi_panel_on2 = false;
		else
			dev_priv->dbi_panel_on = false;

		if (dev_priv->platform_rev_id != MDFLD_PNW_A0)
			mdfld_disable_te(dev, pipe);

		ret = mdfld_panel_generic_dsi_dbi_power_off(encoder);
		if (ret) {
			DRM_ERROR("power on error\n");
			goto out_err;
		}

		dsi_config->dsi_hw_context.panel_on = 0;
	}

out_err:
	mutex_unlock(&dsi_config->context_lock);
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	if (ret)
		DRM_ERROR("failed\n");
	else
		PSB_DEBUG_ENTRY("successfully\n");

	return ret;
}
コード例 #19
0
static int __mdfld_dbi_exit_dsr(struct mdfld_dsi_dbi_output * dbi_output, int pipe)
{
	struct drm_device * dev = dbi_output->dev;
	struct drm_crtc * crtc = dbi_output->base.base.crtc;
	struct psb_intel_crtc * psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL; 
	u32 reg_val;
	u32 dpll_reg = PSB_DSI_PLL_CTRL;
	u32 pipeconf_reg = PSB_PIPECONF(PSB_PIPE_A);
	u32 dspcntr_reg = PSB_DSPCNTR(PSB_PIPE_A);
	u32 dspbase_reg = PSB_DSPBASE(PSB_PIPE_A);
	u32 dspsurf_reg = PSB_DSPSURF(PSB_PIPE_A);

	PSB_DEBUG_ENTRY("\n");

	if(!dbi_output) {
		return 0;
	}

	/*if mode setting on-going, back off*/
	if((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
		(psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) 
		return -EAGAIN;
		
	if(pipe == 2) {
		dpll_reg = PSB_DSI_PLL_CTRL;
		pipeconf_reg = PSB_PIPECONF(PSB_PIPE_C);
		dspcntr_reg = PSB_DSPCNTR(PSB_PIPE_C);
		dspbase_reg = MDFLD_DSPCBASE;
		dspsurf_reg = PSB_DSPSURF(PSB_PIPE_C);
	}

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, true))
		return -EAGAIN;

	/*enable DPLL*/
	reg_val = REG_READ(dpll_reg);
	if(!(reg_val & DPLL_VCO_ENABLE)) {
		
		if(reg_val & MDFLD_PWR_GATE_EN) {
			reg_val &= ~MDFLD_PWR_GATE_EN;
			REG_WRITE(dpll_reg, reg_val);
			REG_READ(dpll_reg);
			udelay(500);
		}
		
		reg_val |= DPLL_VCO_ENABLE;
		REG_WRITE(dpll_reg, reg_val);
		REG_READ(dpll_reg);
		udelay(500);
		
		/*FIXME: add timeout*/
		while (!(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK));
	}
	
	/*enable pipe*/
	reg_val = REG_READ(pipeconf_reg);
	if(!(reg_val & PIPEACONF_ENABLE)) {
		reg_val |= PIPEACONF_ENABLE;
		REG_WRITE(pipeconf_reg, reg_val);
		REG_READ(pipeconf_reg);
		udelay(500);
		mdfldWaitForPipeEnable(dev, pipe);
	}
	
	/*enable plane*/
	reg_val = REG_READ(dspcntr_reg);
	if(!(reg_val & DISPLAY_PLANE_ENABLE)) {
		reg_val |= DISPLAY_PLANE_ENABLE;
		REG_WRITE(dspcntr_reg, reg_val);
		REG_READ(dspcntr_reg);
		udelay(500);
	}
	
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
	
	/*clean IN_DSR flag*/
	dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;
	
	return 0;
}
コード例 #20
0
static int mdfld_dpu_update_fb(struct drm_device * dev) {
	struct drm_crtc * crtc;
	struct psb_intel_crtc * psb_crtc;
	struct mdfld_dsi_dbi_output ** dbi_output;
	struct drm_psb_private * dev_priv = dev->dev_private;
	struct mdfld_dbi_dpu_info * dpu_info = dev_priv->dbi_dpu_info;
	bool pipe_updated[2];
	unsigned long irq_flags;
	u32 dpll_reg = PSB_DSI_PLL_CTRL;
	u32 dspcntr_reg = PSB_DSPCNTR(PSB_PIPE_A);
	u32 pipeconf_reg = PSB_PIPECONF(PSB_PIPE_A);
	u32 dsplinoff_reg = PSB_DSPLINOFF(PSB_PIPE_A);
	u32 dspsurf_reg = PSB_DSPSURF(PSB_PIPE_A);
	int pipe;
	int i;
	int ret;

	dbi_output = dpu_info->dbi_outputs;
	pipe_updated[0] = pipe_updated[1] = false;
	
	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, true))
		return -EAGAIN;

	/*try to prevent any new damage reports*/	
	if(!spin_trylock_irqsave(&dpu_info->dpu_update_lock, irq_flags)) {
		return -EAGAIN;
	}

	for(i=0; i<dpu_info->dbi_output_num; i++) {
		crtc = dbi_output[i]->base.base.crtc;
		psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL; 

                pipe = dbi_output[i]->channel_num ? 2 : 0;

                if(pipe == 2) {
			dspcntr_reg = PSB_DSPCNTR(PSB_PIPE_C);
			pipeconf_reg = PSB_PIPECONF(PSB_PIPE_C);
			dsplinoff_reg = PSB_DSPLINOFF(PSB_PIPE_C);
			dspsurf_reg = PSB_DSPSURF(PSB_PIPE_C);
                }

                if (!(REG_READ(MIPI_GEN_FIFO_STAT_REG(pipe)) & BIT(27)) ||
                   !(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
                   !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
                   !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE)) {
                        PSB_DEBUG_ENTRY("DBI FIFO is busy, DSI %d state %x\n",
                                        pipe,
                                        REG_READ(MIPI_INTR_STAT_REG(pipe)));
                        continue;
                }

		/*if dbi output is in a exclusive state, pipe change won't be updated*/
		if(dbi_output[i]->dbi_panel_on &&
		   !(dbi_output[i]->mode_flags & MODE_SETTING_ON_GOING) &&
		   !(psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING) &&
		   !(dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR)) {
			ret = mdfld_dpu_update_pipe(dbi_output[i], dpu_info, dbi_output[i]->channel_num ? 2 : 0);
			if(!ret) {
				pipe_updated[i] = true;
			}
		} 
	}
	
	for(i=0; i<dpu_info->dbi_output_num; i++) {
		if(pipe_updated[i]) {
			mdfld_dbi_flush_cb(dbi_output[i], dbi_output[i]->channel_num ? 2 : 0);
		}
	}

	spin_unlock_irqrestore(&dpu_info->dpu_update_lock, irq_flags);
	
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
	
	return 0;
}
コード例 #21
0
/**
 * Update the DBI MIPI Panel Frame Buffer.
 */
static void pyr_dsi_dbi_update_fb (struct mdfld_dsi_dbi_output * dbi_output, int pipe)
{
	struct mdfld_dsi_pkg_sender * sender =
		mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
	struct drm_device * dev = dbi_output->dev;
	struct drm_crtc * crtc = dbi_output->base.base.crtc;
	struct psb_intel_crtc * psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL; 

	u32 dpll_reg = MRST_DPLL_A;
	u32 dspcntr_reg = DSPACNTR;
	u32 pipeconf_reg = PIPEACONF;
	u32 dsplinoff_reg = DSPALINOFF;
	u32 dspsurf_reg = DSPASURF;
	/*u32 mipi_state_reg = MIPIA_INTR_STAT_REG;*/
	u32 hs_gen_ctrl_reg = HS_GEN_CTRL_REG;
	u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
	u32 reg_offset = 0;

	u32 intr_status;
	u32 fifo_stat_reg_val;
	u32 dpll_reg_val;
	u32 dspcntr_reg_val;
	u32 pipeconf_reg_val;

	/*if mode setting on-going, back off*/
	if((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
		(psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING) ||
		!(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE))
		return;

	/*
	 * Look for errors here.  In particular we're checking for whatever
 	 * error status might have appeared during the last frame transmit
 	 * (memory write).
 	 *
 	 * Normally, the bits we're testing here would be set infrequently,
 	 * if at all.  However, the Pyrenees panel (at least) returns
 	 * at least one error bit on most frames.  So we've disabled the
 	 * kernel message for now.
 	 *
 	 * Still clear whatever error bits are set, except don't clear the
 	 * ones that would make the Penwell DSI controller reset if we
 	 * cleared them.
 	 */
	intr_status = REG_READ(INTR_STAT_REG);
	if ((intr_status & 0x26FFFFFF) != 0) {
		/* DRM_ERROR("DSI status: 0x%08X\n", intr_status); */
		intr_status &= 0x26F3FFFF;
	        REG_WRITE(INTR_STAT_REG, intr_status);
	}
		
	if(pipe == 2) {
		dspcntr_reg = DSPCCNTR;
		pipeconf_reg = PIPECCONF;
		dsplinoff_reg = DSPCLINOFF;
		dspsurf_reg = DSPCSURF;

		hs_gen_ctrl_reg = HS_GEN_CTRL_REG + MIPIC_REG_OFFSET;
		gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET,

		reg_offset = MIPIC_REG_OFFSET;
	}

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) {
		DRM_ERROR("hw begin failed\n");
		return;
	}

	fifo_stat_reg_val = REG_READ(MIPIA_GEN_FIFO_STAT_REG + reg_offset);
	dpll_reg_val = REG_READ(dpll_reg);
	dspcntr_reg_val = REG_READ(dspcntr_reg);
	pipeconf_reg_val = REG_READ(pipeconf_reg);

	if(!(fifo_stat_reg_val & BIT27) ||
	   !(dpll_reg_val & DPLL_VCO_ENABLE) ||
	   !(dspcntr_reg_val & DISPLAY_PLANE_ENABLE) ||
	   !(pipeconf_reg_val & DISPLAY_PLANE_ENABLE)) {
		goto update_fb_out0;
	}
	
	/*refresh plane changes*/
	REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
	REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
	REG_READ(dspsurf_reg);

	mdfld_dsi_send_dcs(sender,
			   write_mem_start,
			   NULL,
			   0,
			   CMD_DATA_SRC_PIPE,
			   MDFLD_DSI_SEND_PACKAGE);

	/*
	* The idea here is to transmit a Generic Read command after the
	* Write Memory Start/Continue commands finish.  This asks for
	* the panel to return an "ACK No Errors," or (if it has errors
	* to report) an Error Report.  This allows us to monitor the
	* panel's perception of the health of the DSI.
	*/

	mdfld_dsi_gen_fifo_ready (dev, gen_fifo_stat_reg, HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
	REG_WRITE(hs_gen_ctrl_reg, (1 << WORD_COUNTS_POS) | GEN_READ_0);

	dbi_output->dsr_fb_update_done = true;
update_fb_out0:
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
}
コード例 #22
0
static void pyr_dsi_dbi_mode_set(struct drm_encoder * encoder,
				   struct drm_display_mode * mode,
				   struct drm_display_mode * adjusted_mode)
{
	int ret = 0;
	struct drm_device * dev = encoder->dev;
	struct drm_psb_private * dev_priv = (struct drm_psb_private*)dev->dev_private;
	struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output * dsi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	struct mdfld_dsi_config * dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
	struct mdfld_dsi_connector * dsi_connector = dsi_config->connector;
	int pipe = dsi_connector->pipe;
	u8 param = 0;
	
	/*regs*/
	u32 mipi_reg = MIPI;
	u32 dspcntr_reg = DSPACNTR;
	u32 pipeconf_reg = PIPEACONF;
	u32 reg_offset = 0;
	
	/*values*/
	u32 dspcntr_val = dev_priv->dspcntr;
	u32 pipeconf_val = dev_priv->pipeconf;
	u32 h_active_area = mode->hdisplay; 
	u32 v_active_area = mode->vdisplay; 
	u32 mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX);

	if (dev_priv->platform_rev_id != MDFLD_PNW_A0)
		mipi_val = (PASS_FROM_SPHY_TO_AFE | TE_TRIGGER_GPIO_PIN);

	PSB_DEBUG_ENTRY("mipi_val =0x%x\n", mipi_val);

	PSB_DEBUG_ENTRY("type %s\n", (pipe == 2) ? "MIPI2" : "MIPI");
	PSB_DEBUG_ENTRY("h %d v %d\n", mode->hdisplay, mode->vdisplay);

	if(pipe == 2) {
		mipi_reg = MIPI_C;
		dspcntr_reg = DSPCCNTR;
		pipeconf_reg = PIPECCONF;
		
		reg_offset = MIPIC_REG_OFFSET;
		
		dspcntr_val = dev_priv->dspcntr2;
		pipeconf_val = dev_priv->pipeconf2;
	} else {
		mipi_val |= 0x2; /*two lanes for port A and C respectively*/
	}

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) {
		DRM_ERROR("hw begin failed\n");
		return;
	}
	
	/*set up pipe related registers*/
	REG_WRITE(mipi_reg, mipi_val);
	REG_READ(mipi_reg);
	
	pyr_dsi_controller_dbi_init(dsi_config, pipe);
	
	msleep(20);
	
	REG_WRITE(dspcntr_reg, dspcntr_val);
	REG_READ(dspcntr_reg);
    
	/*20ms delay before sending exit_sleep_mode*/
	msleep(20);
    
	/*send exit_sleep_mode DCS*/
	ret = mdfld_dsi_dbi_send_dcs(dsi_output, exit_sleep_mode, NULL, 0, CMD_DATA_SRC_SYSTEM_MEM);
	if(ret) {
		DRM_ERROR("sent exit_sleep_mode faild\n");
		goto out_err;
	}

	if (dev_priv->platform_rev_id != MDFLD_PNW_A0) {
		/*send set_tear_on DCS*/
		ret = mdfld_dsi_dbi_send_dcs(dsi_output, set_tear_on, &param, 1, CMD_DATA_SRC_SYSTEM_MEM);

		if(ret) {
			DRM_ERROR("%s - sent set_tear_on faild\n", __func__);
			goto out_err;
		}
	}

	/*do some init stuff*/
	mdfld_dsi_brightness_init(dsi_config, pipe);
	
	mdfld_dsi_gen_fifo_ready (dev, (MIPIA_GEN_FIFO_STAT_REG + reg_offset), HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);

	REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR);
	REG_READ(pipeconf_reg);
	
	/*TODO: this looks ugly, try to move it to CRTC mode setting*/
	if(pipe == 2) {
		dev_priv->pipeconf2 |= PIPEACONF_DSR;
	} else {
		dev_priv->pipeconf |= PIPEACONF_DSR;
	}
	
	PSB_DEBUG_ENTRY("pipeconf %x\n",  REG_READ(pipeconf_reg));
	
	ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0, h_active_area - 1, v_active_area - 1);
	if(ret) {
		DRM_ERROR("update area failed\n");
		goto out_err;
	}

out_err:
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	if(ret) {
		DRM_ERROR("mode set failed\n");
	} else {
		PSB_DEBUG_ENTRY("mode set done successfully\n");
	}
}
コード例 #23
0
static void pyr_dsi_dbi_set_power(struct drm_encoder * encoder, bool on)
{
	int ret = 0;
	struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder);
	struct mdfld_dsi_dbi_output * dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
	/*struct drm_device * dev = dbi_output->dev;*/
	struct drm_device* dev = encoder->dev;
	struct drm_psb_private * dev_priv = dev->dev_private;
	u32 reg_offset = 0;
	int pipe = (dbi_output->channel_num == 0) ? 0 : 2;

	PSB_DEBUG_ENTRY("pipe %d : %s, panel on: %s\n",pipe, on ? "On" : "Off", dbi_output->dbi_panel_on ? "True" : "False");
        
	if(pipe == 2) {
		if(on)
			dev_priv->dual_mipi = true;
		else
			dev_priv->dual_mipi = false;

		reg_offset = MIPIC_REG_OFFSET;
	} else {
		if (!on)
			dev_priv->dual_mipi = false;
	}

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) {
		DRM_ERROR("hw begin failed\n");
		return;
	}


	if(on) {
		if(dbi_output->dbi_panel_on)
			goto out_err;
					
		ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON);
		if(ret) {
			DRM_ERROR("power on error\n");
			goto out_err;
		}

		dbi_output->dbi_panel_on = true;

		if(pipe == 2) {
			dev_priv->dbi_panel_on2 = true;
		} else {
			dev_priv->dbi_panel_on = true;

			if (dev_priv->platform_rev_id != MDFLD_PNW_A0)
				mdfld_enable_te(dev, 0);
		}
		
	} else {
		if(!dbi_output->dbi_panel_on && !dbi_output->first_boot) 
			goto out_err;
					
		dbi_output->dbi_panel_on = false;
		dbi_output->first_boot = false;

		if(pipe == 2) {
			dev_priv->dbi_panel_on2 = false;

			if (dev_priv->platform_rev_id != MDFLD_PNW_A0)
				mdfld_disable_te(dev, 2);
		} else {
			dev_priv->dbi_panel_on = false;

			if (dev_priv->platform_rev_id != MDFLD_PNW_A0) {
				mdfld_disable_te(dev, 0);

				if (dev_priv->dbi_panel_on2)
					mdfld_enable_te(dev, 2);
			}
		}

		ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF);
		if(ret) {
			DRM_ERROR("power on error\n");
			goto out_err;
		}
	}

out_err:
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	if(ret)
		DRM_ERROR("failed\n");
	else
		PSB_DEBUG_ENTRY("successfully\n");
}
コード例 #24
0
int psb_hist_enable(struct drm_device *dev, void *data)
{
	u32 irqCtrl = 0;
	struct drm_psb_private *dev_priv = psb_priv(dev);
	struct dpst_guardband guardband_reg;
	struct dpst_ie_histogram_control ie_hist_cont_reg;
	struct mdfld_dsi_hw_context *ctx = NULL;
	uint32_t *enable = data;
	struct mdfld_dsi_config *dsi_config = NULL;

	if (!dev_priv)
		return 0;
	dsi_config = dev_priv->dsi_configs[0];
	if (!dsi_config)
		return 0;
	ctx = &dsi_config->dsi_hw_context;

	if (!ospm_power_using_hw_begin
	    (OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) {
		return 0;
	}
	mdfld_dsi_dsr_forbid(dsi_config);

	if (*enable == 1) {
		ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
		ie_hist_cont_reg.ie_pipe_assignment = 0;
		ie_hist_cont_reg.histogram_mode_select = DPST_YUV_LUMA_MODE;
		ie_hist_cont_reg.ie_histogram_enable = 1;
		PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL);
		ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;

		guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
		guardband_reg.interrupt_enable = 1;
		guardband_reg.interrupt_status = 1;
		PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
		ctx->histogram_intr_ctrl = guardband_reg.data;

		irqCtrl = PSB_RVDC32(PIPEASTAT);
		ctx->pipestat = (irqCtrl | PIPE_DPST_EVENT_ENABLE);
		PSB_WVDC32(ctx->pipestat, PIPEASTAT);
	} else {
		guardband_reg.data = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
		guardband_reg.interrupt_enable = 0;
		guardband_reg.interrupt_status = 1;
		PSB_WVDC32(guardband_reg.data, HISTOGRAM_INT_CONTROL);
		ctx->histogram_intr_ctrl = guardband_reg.data;

		ie_hist_cont_reg.data = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
		ie_hist_cont_reg.ie_histogram_enable = 0;
		PSB_WVDC32(ie_hist_cont_reg.data, HISTOGRAM_LOGIC_CONTROL);
		ctx->histogram_logic_ctrl = ie_hist_cont_reg.data;

		irqCtrl = PSB_RVDC32(PIPEASTAT);
		irqCtrl &= ~PIPE_DPST_EVENT_ENABLE;
		PSB_WVDC32(irqCtrl, PIPEASTAT);
		ctx->pipestat = irqCtrl;
		dpst_disable_post_process(g_dev);
	}

	mdfld_dsi_dsr_allow(dsi_config);
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	return 0;
}
コード例 #25
0
/**
 * snd_intelhad_init_audio_ctrl - to initialize audio channel status
 * registers and confgiuration registers
 *
 * @substream:substream for which the prepare function is called
 * @intelhaddata:substream private data
 *
 * This function is called in the prepare callback
 */
int snd_intelhad_init_audio_ctrl(struct snd_pcm_substream *substream,
					struct snd_intelhad *intelhaddata,
					int flag_silence)
{
	union aud_cfg cfg_val = {.cfg_regval = 0};
	union aud_ch_status_0 ch_stat0 = {.status_0_regval = 0};
	union aud_ch_status_1 ch_stat1 = {.status_1_regval = 0};
	union aud_buf_config buf_cfg = {.buf_cfgval = 0};
	u8 channels;
	int format, retval;
	u32 data;

	ch_stat0.status_0_regx.lpcm_id = (intelhaddata->aes_bits &
						IEC958_AES0_NONAUDIO)>>1;
	ch_stat0.status_0_regx.clk_acc = (intelhaddata->aes_bits &
						IEC958_AES3_CON_CLOCK)>>4;
	switch (substream->runtime->rate) {
	case AUD_SAMPLE_RATE_32:
		ch_stat0.status_0_regx.samp_freq = CH_STATUS_MAP_32KHZ;
	break;

	case AUD_SAMPLE_RATE_44_1:
	case AUD_SAMPLE_RATE_88_2:
	case AUD_SAMPLE_RATE_176_4:
		ch_stat0.status_0_regx.samp_freq = CH_STATUS_MAP_44KHZ;
	break;

	case AUD_SAMPLE_RATE_48:
	case AUD_SAMPLE_RATE_96:
	case HAD_MAX_RATE:
		ch_stat0.status_0_regx.samp_freq = CH_STATUS_MAP_48KHZ;
	break;

	default:
		return -EINVAL;
	break;

	}
	had_write_register(AUD_CH_STATUS_0, ch_stat0.status_0_regval);

	format = substream->runtime->format;

	if (format == SNDRV_PCM_FORMAT_S16_LE) {
		ch_stat1.status_1_regx.max_wrd_len = MAX_SMPL_WIDTH_20;
		ch_stat1.status_1_regx.wrd_len = SMPL_WIDTH_16BITS;
	} else if (format == SNDRV_PCM_FORMAT_S24_LE) {
		ch_stat1.status_1_regx.max_wrd_len = MAX_SMPL_WIDTH_24;
		ch_stat1.status_1_regx.wrd_len = SMPL_WIDTH_24BITS;
	} else {
		ch_stat1.status_1_regx.max_wrd_len = 0;
		ch_stat1.status_1_regx.wrd_len = 0;
	}
	had_write_register(AUD_CH_STATUS_1, ch_stat1.status_1_regval);

	buf_cfg.buf_cfg_regx.fifo_width = FIFO_THRESHOLD;
	buf_cfg.buf_cfg_regx.aud_delay = 0;
	had_write_register(AUD_BUF_CONFIG, buf_cfg.buf_cfgval);

	channels = substream->runtime->channels;

	switch (channels) {
	case 1:
	case 2:
		cfg_val.cfg_regx.num_ch = CH_STEREO;
		cfg_val.cfg_regx.layout = LAYOUT0;
	break;

	case 3:
	case 4:
		cfg_val.cfg_regx.num_ch = CH_THREE_FOUR;
		cfg_val.cfg_regx.layout = LAYOUT1;
	break;

	case 5:
	case 6:
		cfg_val.cfg_regx.num_ch = CH_FIVE_SIX;
		cfg_val.cfg_regx.layout = LAYOUT1;
	break;

	case 7:
	case 8:
		cfg_val.cfg_regx.num_ch = CH_SEVEN_EIGHT;
		cfg_val.cfg_regx.layout = LAYOUT1;
	break;

	}

	cfg_val.cfg_regx.val_bit = 1;
	had_write_register(AUD_CONFIG, cfg_val.cfg_regval);
	return 0;
}

/**
 * snd_intelhad_prog_dip - to initialize Data Island Packets registers
 *
 * @substream:substream for which the prepare function is called
 * @intelhaddata:substream private data
 *
 * This function is called in the prepare callback
 */
static void snd_intelhad_prog_dip(struct snd_pcm_substream *substream,
				struct snd_intelhad *intelhaddata,
				int flag_silence)
{
	int i;
	union aud_ctrl_st ctrl_state = {.ctrl_val = 0};
	union aud_info_frame2 frame2 = {.fr2_val = 0};
	union aud_info_frame3 frame3 = {.fr3_val = 0};
	u8 checksum = 0;

	had_write_register(AUD_CNTL_ST, ctrl_state.ctrl_val);

	frame2.fr2_regx.chnl_cnt = substream->runtime->channels - 1;

	/*TODO: Read from intelhaddata->eeld.speaker_allocation_block;*/
	frame3.fr3_regx.chnl_alloc = CHANNEL_ALLOCATION;

	/*Calculte the byte wide checksum for all valid DIP words*/
	for (i = 0; i < BYTES_PER_WORD; i++)
		checksum += (INFO_FRAME_WORD1 >> i*BITS_PER_BYTE) & MASK_BYTE0;
	for (i = 0; i < BYTES_PER_WORD; i++)
		checksum += (frame2.fr2_val >> i*BITS_PER_BYTE) & MASK_BYTE0;
	for (i = 0; i < BYTES_PER_WORD; i++)
		checksum += (frame3.fr3_val >> i*BITS_PER_BYTE) & MASK_BYTE0;

	frame2.fr2_regx.chksum = -(checksum);

	had_write_register(AUD_HDMIW_INFOFR, INFO_FRAME_WORD1);
	had_write_register(AUD_HDMIW_INFOFR, frame2.fr2_val);
	had_write_register(AUD_HDMIW_INFOFR, frame3.fr3_val);

	/* program remaining DIP words with zero */
	for (i = 0; i < HAD_MAX_DIP_WORDS-VALID_DIP_WORDS; i++)
		had_write_register(AUD_HDMIW_INFOFR, 0x0);

	ctrl_state.ctrl_regx.dip_freq = 1;
	ctrl_state.ctrl_regx.dip_en_sta = 1;
	had_write_register(AUD_CNTL_ST, ctrl_state.ctrl_val);
}

/**
 * snd_intelhad_prog_buffer - programs buffer
 * address and length registers
 *
 * @substream:substream for which the prepare function is called
 * @intelhaddata:substream private data
 *
 * This function programs ring buffer address and length into registers.
 */
int snd_intelhad_prog_buffer(struct snd_intelhad *intelhaddata,
					int start, int end)
{
	u32 ring_buf_addr, ring_buf_size, period_bytes;
	u8 i, num_periods;
	struct snd_pcm_substream *substream;

	substream = intelhaddata->stream_info.had_substream;
	if (!substream) {
		pr_err("substream is NULL\n");
		dump_stack();
		return 0;
	}

	ring_buf_addr = substream->runtime->dma_addr;
	ring_buf_size = snd_pcm_lib_buffer_bytes(substream);
	intelhaddata->stream_info.ring_buf_size = ring_buf_size;
	period_bytes = frames_to_bytes(substream->runtime,
				substream->runtime->period_size);
	num_periods = substream->runtime->periods;

	/* buffer addr should  be 64 byte aligned, period bytes
	 will be used to calculate addr offset*/
	period_bytes &= ~0x3F;

	/* Hardware supports MAX_PERIODS buffers */
	if (end >= HAD_MAX_PERIODS)
		return -EINVAL;

	for (i = start; i <= end; i++) {
		/* Program the buf registers with addr and len */
		intelhaddata->buf_info[i].buf_addr = ring_buf_addr +
							 (i * period_bytes);
		if (i < num_periods-1)
			intelhaddata->buf_info[i].buf_size = period_bytes;
		else
			intelhaddata->buf_info[i].buf_size = ring_buf_size -
							(period_bytes*i);

		had_write_register(AUD_BUF_A_ADDR + (i * HAD_REG_WIDTH),
					intelhaddata->buf_info[i].buf_addr |
					BIT(0) | BIT(1));
		had_write_register(AUD_BUF_A_LENGTH + (i * HAD_REG_WIDTH),
					period_bytes);
		intelhaddata->buf_info[i].is_valid = true;
	}
	pr_debug("%s:buf[%d-%d] addr=%#x  and size=%d\n", __func__, start, end,
			intelhaddata->buf_info[start].buf_addr,
			intelhaddata->buf_info[start].buf_size);
	intelhaddata->valid_buf_cnt = num_periods;
	return 0;
}

inline int snd_intelhad_read_len(struct snd_intelhad *intelhaddata)
{
	int i, retval = 0;
	u32 len[4];

	for (i = 0; i < 4 ; i++) {
		had_read_register(AUD_BUF_A_LENGTH + (i * HAD_REG_WIDTH),
					&len[i]);
		if (!len[i])
			retval++;
	}
	if (retval != 1) {
		for (i = 0; i < 4 ; i++)
			pr_debug("buf[%d] size=%d\n", i, len[i]);
	}

	return retval;
}

/**
 * snd_intelhad_prog_cts - Program HDMI audio CTS value
 *
 * @aud_samp_freq: sampling frequency of audio data
 * @tmds: sampling frequency of the display data
 * @n_param: N value, depends on aud_samp_freq
 * @intelhaddata:substream private data
 *
 * Program CTS register based on the audio and display sampling frequency
 */
static void snd_intelhad_prog_cts(u32 aud_samp_freq, u32 tmds, u32 n_param,
				struct snd_intelhad *intelhaddata)
{
	u32 cts_val;
	u64 dividend, divisor;

	/* Calculate CTS according to HDMI 1.3a spec*/
	dividend = (u64)tmds * n_param*1000;
	divisor = 128 * aud_samp_freq;
	cts_val = div64_u64(dividend, divisor);
	pr_debug("TMDS value=%d, N value=%d, CTS Value=%d\n",
			tmds, n_param, cts_val);
	had_write_register(AUD_HDMI_CTS, (BIT(20) | cts_val));
}

/**
 * snd_intelhad_prog_n - Program HDMI audio N value
 *
 * @aud_samp_freq: sampling frequency of audio data
 * @n_param: N value, depends on aud_samp_freq
 * @intelhaddata:substream private data
 *
 * This function is called in the prepare callback.
 * It programs based on the audio and display sampling frequency
 */
static int snd_intelhad_prog_n(u32 aud_samp_freq, u32 *n_param,
				struct snd_intelhad *intelhaddata)
{
	u32 n_val;
	int retval = 0;

	/* Select N according to HDMI 1.3a spec*/
	switch (aud_samp_freq) {
	case AUD_SAMPLE_RATE_32:
		n_val = 4096;
	break;

	case AUD_SAMPLE_RATE_44_1:
		n_val = 6272;
	break;

	case AUD_SAMPLE_RATE_48:
		n_val = 6144;
	break;

	case AUD_SAMPLE_RATE_88_2:
		n_val = 12544;
	break;

	case AUD_SAMPLE_RATE_96:
		n_val = 12288;
	break;

	case AUD_SAMPLE_RATE_176_4:
		n_val = 25088;
	break;

	case HAD_MAX_RATE:
		n_val = 24576;
	break;

	default:
		retval = -EINVAL;
	break;

	}
	if (retval)
		return retval;
	had_write_register(AUD_N_ENABLE, (BIT(20) | n_val));
	*n_param = n_val;
	return retval;
}

/**
* snd_intelhad_open - stream initializations are done here
* @substream:substream for which the stream function is called
*
* This function is called whenever a PCM stream is opened
*/
static int snd_intelhad_open(struct snd_pcm_substream *substream)
{
	struct snd_intelhad *intelhaddata;
	struct snd_pcm_runtime *runtime;
	struct had_stream_pvt *stream;
	struct had_pvt_data *had_stream;
	int retval;

	pr_debug("snd_intelhad_open called\n");
	intelhaddata = snd_pcm_substream_chip(substream);
	had_stream = intelhaddata->private_data;

	/*
	 * HDMI driver might suspend the device already,
	 * so we return it on
	 */
	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
			OSPM_UHB_FORCE_POWER_ON)) {
		pr_err("HDMI device can't be turned on\n");
		return -ENODEV;
	}

	if (had_get_hwstate(intelhaddata)) {
		pr_err("%s: HDMI cable plugged-out\n", __func__);
		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
		return -ENODEV;
	}
	runtime = substream->runtime;

	/* Check, if device already in use */
	if (runtime->private_data) {
		pr_err("Device already in use\n");
		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
		return -EBUSY;
	}

	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	/* set the runtime hw parameter with local snd_pcm_hardware struct */
	runtime->hw = snd_intel_hadstream;

	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
	if (!stream) {
		retval = -ENOMEM;
		goto exit_err;
	}
	stream->stream_status = STREAM_INIT;
	runtime->private_data = stream;

	retval = snd_pcm_hw_constraint_integer(runtime,
			 SNDRV_PCM_HW_PARAM_PERIODS);
	if (retval < 0) {
		kfree(stream);
		goto exit_err;
	}

	/* Make sure, that the period size is always aligned
	 * 64byte boundary
	 */
	retval = snd_pcm_hw_constraint_step(substream->runtime, 0,
			SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64);
	if (retval < 0) {
		pr_err("%s:step_size=64 failed,err=%d\n", __func__, retval);
		kfree(stream);
		goto exit_err;
	}

	return retval;
exit_err:
	runtime->private_data = NULL;
	return retval;
}

/**
* had_period_elapsed - updates the hardware pointer status
* @had_substream:substream for which the stream function is called
*
*/
static void had_period_elapsed(void *had_substream)
{
	struct snd_pcm_substream *substream = had_substream;
	struct had_stream_pvt *stream;

	if (!substream || !substream->runtime)
		return;
	stream = substream->runtime->private_data;
	if (!stream)
		return;

	if (stream->stream_status != STREAM_RUNNING)
		return;
	snd_pcm_period_elapsed(substream);
	return;
}

/**
* snd_intelhad_init_stream - internal function to initialize stream info
* @substream:substream for which the stream function is called
*
*/
static int snd_intelhad_init_stream(struct snd_pcm_substream *substream)
{
	struct snd_intelhad *intelhaddata = snd_pcm_substream_chip(substream);

	pr_debug("setting buffer ptr param\n");
	intelhaddata->stream_info.period_elapsed = had_period_elapsed;
	intelhaddata->stream_info.had_substream = substream;
	intelhaddata->stream_info.buffer_ptr = 0;
	intelhaddata->stream_info.buffer_rendered = 0;
	intelhaddata->stream_info.sfreq = substream->runtime->rate;
	return 0;
}

/**
 * snd_intelhad_close- to free parameteres when stream is stopped
 *
 * @substream:  substream for which the function is called
 *
 * This function is called by ALSA framework when stream is stopped
 */
static int snd_intelhad_close(struct snd_pcm_substream *substream)
{
	struct snd_intelhad *intelhaddata;
	struct snd_pcm_runtime *runtime;

	pr_debug("snd_intelhad_close called\n");
	intelhaddata = snd_pcm_substream_chip(substream);
	runtime = substream->runtime;

	intelhaddata->stream_info.buffer_rendered = 0;
	intelhaddata->stream_info.buffer_ptr = 0;
	intelhaddata->stream_info.str_id = 0;
	intelhaddata->stream_info.had_substream = NULL;

	/* Check if following drv_status modification is required - VA */
	if (intelhaddata->drv_status != HAD_DRV_DISCONNECTED)
		intelhaddata->drv_status = HAD_DRV_CONNECTED;
	kfree(runtime->private_data);
	runtime->private_data = NULL;
	return 0;
}

/**
 * snd_intelhad_hw_params- to setup the hardware parameters
 * like allocating the buffers
 *
 * @substream:  substream for which the function is called
 * @hw_params: hardware parameters
 *
 * This function is called by ALSA framework when hardware params are set
 */
static int snd_intelhad_hw_params(struct snd_pcm_substream *substream,
				    struct snd_pcm_hw_params *hw_params)
{
	unsigned long addr;
	int pages, buf_size, retval;

	BUG_ON(!hw_params);

	buf_size = params_buffer_bytes(hw_params);
	retval = snd_pcm_lib_malloc_pages(substream, buf_size);
	if (retval < 0)
		return retval;
	pr_debug("%s:allocated memory = %d\n", __func__, buf_size);
	/* mark the pages as uncached region */
	addr = (unsigned long) substream->runtime->dma_area;
	pages = (substream->runtime->dma_bytes + PAGE_SIZE - 1) / PAGE_SIZE;
	retval = set_memory_uc(addr, pages);
	if (retval) {
		pr_err("set_memory_uc failed.Error:%d\n", retval);
		return retval;
	}
	memset(substream->runtime->dma_area, 0, buf_size);

	return retval;
}

/**
 * snd_intelhad_hw_free- to release the resources allocated during
 * hardware params setup
 *
 * @substream:  substream for which the function is called
 *
 * This function is called by ALSA framework before close callback.
 *
 */
static int snd_intelhad_hw_free(struct snd_pcm_substream *substream)
{
	unsigned long addr;
	u32 pages;

	pr_debug("snd_intelhad_hw_free called\n");

	/* mark back the pages as cached/writeback region before the free */
	addr = (unsigned long) substream->runtime->dma_area;
	pages = (substream->runtime->dma_bytes + PAGE_SIZE - 1) / PAGE_SIZE;
	set_memory_wb(addr, pages);
	return snd_pcm_lib_free_pages(substream);
}
コード例 #26
0
void mdfld_panel_generic_dsi_dbi_update_fb(
	struct mdfld_dsi_dbi_output *dbi_output,
	int pipe)
{
	struct mdfld_dsi_pkg_sender *sender =
		mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
	struct drm_device *dev = dbi_output->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct drm_crtc *crtc = dbi_output->base.base.crtc;
	struct psb_intel_crtc *psb_crtc =
		(crtc) ? to_psb_intel_crtc(crtc) : NULL;
	u32 dpll_reg = MRST_DPLL_A;
	u32 dspcntr_reg = DSPACNTR;
	u32 pipeconf_reg = PIPEACONF;
	u32 dsplinoff_reg = DSPALINOFF;
	u32 dspsurf_reg = DSPASURF;

	if (!dev_priv->dsi_init_done)
		return;

	/* if mode setting on-going, back off */
	if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
			(psb_crtc &&
			 (psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) ||
			!(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE))
		return;

	if (pipe == 2) {
		dspcntr_reg = DSPCCNTR;
		pipeconf_reg = PIPECCONF;
		dsplinoff_reg = DSPCLINOFF;
		dspsurf_reg = DSPCSURF;
	}

	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
				OSPM_UHB_FORCE_POWER_ON)) {
		DRM_ERROR("hw begin failed\n");
		return;
	}

	/* check DBI FIFO status */
	if (!(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
	   !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
	   !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE)) {
		goto update_fb_out0;
	}

	/* refresh plane changes */
	REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
	REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
	REG_READ(dspsurf_reg);

	mdfld_dsi_send_dcs(sender,
			   write_mem_start,
			   NULL,
			   0,
			   CMD_DATA_SRC_PIPE,
			   MDFLD_DSI_SEND_PACKAGE);

	dbi_output->dsr_fb_update_done = true;


update_fb_out0:
	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
}
コード例 #27
0
static int enter_dsr_locked(struct mdfld_dsi_config *dsi_config, int level)
{
	u32 val = 0;
	struct mdfld_dsi_hw_registers *regs;
	struct mdfld_dsi_hw_context *ctx;
	struct drm_psb_private *dev_priv;
	struct drm_device *dev;
	struct mdfld_dsi_pkg_sender *sender;
	int err;
	pm_message_t state;
	int pipe0_enabled;
	int pipe2_enabled;

	PSB_DEBUG_ENTRY("mdfld_dsi_dsr: enter dsr\n");

	if (!dsi_config)
		return -EINVAL;

	regs = &dsi_config->regs;
	ctx = &dsi_config->dsi_hw_context;
	dev = dsi_config->dev;
	dev_priv = dev->dev_private;

	sender = mdfld_dsi_get_pkg_sender(dsi_config);
	if (!sender) {
		DRM_ERROR("Failed to get dsi sender\n");
		return -EINVAL;
	}

	if (level < DSR_EXITED) {
		DRM_ERROR("Why to do this?");
		return -EINVAL;
	}

	if (level > DSR_ENTERED_LEVEL0) {
		/**
		 * TODO: require OSPM interfaces to tell OSPM module that
		 * display controller is ready to be power gated.
		 * OSPM module needs to response this request ASAP.
		 * NOTE: it makes no sense to have display controller islands
		 * & pci power gated here directly. OSPM module is the only one
		 * who can power gate/ungate power islands.
		 * FIXME: since there's no ospm interfaces for acquiring
		 * suspending DSI related power islands, we have to call OSPM
		 * interfaces to power gate display islands and pci right now,
		 * which should NOT happen in this way!!!
		 */
		if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
			OSPM_UHB_FORCE_POWER_ON)) {
			DRM_ERROR("Failed power on display island\n");
			return -EINVAL;
		}

		PSB_DEBUG_ENTRY("mdfld_dsi_dsr: entering DSR level 1\n");

		/*Disable TE, don't need it anymore*/
		mdfld_disable_te(dev, dsi_config->pipe);
		err = mdfld_dsi_wait_for_fifos_empty(sender);
		if (err) {
			DRM_ERROR("mdfld_dsi_dsr: FIFO not empty\n");
			mdfld_enable_te(dev, dsi_config->pipe);
			ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
			return err;
		}
		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

		/*suspend whole PCI host and related islands
		** if failed at this try, revive te for another chance
		*/
		state.event = 0;
		if (ospm_power_suspend(gpDrmDevice->pdev, state)) {
			/* Only display island is powered off then
			 ** need revive the whole TE
			 */
			if (!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND))
				exit_dsr_locked(dsi_config);
			else
				mdfld_enable_te(dev, dsi_config->pipe);
			return -EINVAL;
		}
		/*
		 *suspend pci
		 *FIXME: should I do it here?
		 *how about decoder/encoder is working??
		 *OSPM should check the refcout of each islands before
		 *actually power off PCI!!!
		 *need invoke this in the same context, we need deal with
		 *DSR lock later for suspend PCI may go to sleep!!!
		 */
		/*ospm_suspend_pci(dev->pdev);*/

		PSB_DEBUG_ENTRY("mdfld_dsi_dsr: entered\n");
		return 0;
	}

	/*
	 * if DSR_EXITED < level < DSR_ENTERED_LEVEL1, we only have the display
	 * controller components turned off instead of power gate them.
	 * this is useful for HDMI & WIDI.
	 */
	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
		OSPM_UHB_FORCE_POWER_ON)) {
		DRM_ERROR("Failed power on display island\n");
		return -EINVAL;
	}

	PSB_DEBUG_ENTRY("mdfld_dsi_dsr: entering DSR level 0\n");

	/*Disable TE, don't need it anymore*/
	mdfld_disable_te(dev, dsi_config->pipe);
	err = mdfld_dsi_wait_for_fifos_empty(sender);
	if (err) {
		DRM_ERROR("mdfld_dsi_dsr: FIFO not empty\n");
		mdfld_enable_te(dev, dsi_config->pipe);
		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
		return err;
	}

	/*turn off dbi interface put in ulps*/
	__dbi_power_off(dsi_config);

	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);

	PSB_DEBUG_ENTRY("entered\n");
	return 0;
}
コード例 #28
0
bool ps_hdmi_power_islands_on()
{
	return ospm_power_using_hw_begin(
			OSPM_DISPLAY_B | OSPM_DISPLAY_HDMI,
			OSPM_UHB_FORCE_POWER_ON);
}
コード例 #29
0
ファイル: h8c7_cmd.c プロジェクト: DanBjorklund/ME302C
static
void mdfld_h8c7_dsi_controller_init(struct mdfld_dsi_config *dsi_config)
{

	struct mdfld_dsi_hw_context *hw_ctx = &dsi_config->dsi_hw_context;
	struct drm_device *dev = dsi_config->dev;

	struct csc_setting csc = {	.pipe = 0,
								.type = CSC_REG_SETTING,
								.enable_state = true,
								.data_len = CSC_REG_COUNT,
								.data.csc_reg_data = {
									0xFFB0424, 0xFDF, 0x4320FF1, 0xFDC, 0xFF50FF5, 0x415}
							 };
	struct gamma_setting gamma = {	.pipe = 0,
									.type = GAMMA_REG_SETTING,
									.enable_state = true,
									.data_len = GAMMA_10_BIT_TABLE_COUNT,
									.gamma_tableX100 = {
										0x000000, 0x030303, 0x050505, 0x070707,
										0x090909, 0x0C0C0C, 0x0E0E0E, 0x101010,
										0x121212, 0x141414, 0x171717, 0x191919,
										0x1B1B1B, 0x1D1D1D, 0x1F1F1F, 0x212121,
										0x232323, 0x252525, 0x282828, 0x2A2A2A,
										0x2C2C2C, 0x2E2E2E, 0x303030, 0x323232,
										0x343434, 0x363636, 0x383838, 0x3A3A3A,
										0x3C3C3C, 0x3E3E3E, 0x404040, 0x424242,
										0x444444, 0x464646, 0x484848, 0x4A4A4A,
										0x4C4C4C, 0x4E4E4E, 0x505050, 0x525252,
										0x545454, 0x565656, 0x585858, 0x5A5A5A,
										0x5C5C5C, 0x5E5E5E, 0x606060, 0x626262,
										0x646464, 0x666666, 0x686868, 0x6A6A6A,
										0x6C6C6C, 0x6E6E6E, 0x707070, 0x727272,
										0x747474, 0x767676, 0x787878, 0x7A7A7A,
										0x7C7C7C, 0x7E7E7E, 0x808080, 0x828282,
										0x848484, 0x868686, 0x888888, 0x8A8A8A,
										0x8C8C8C, 0x8E8E8E, 0x909090, 0x929292,
										0x949494, 0x969696, 0x989898, 0x999999,
										0x9B9B9B, 0x9D9D9D, 0x9F9F9F, 0xA1A1A1,
										0xA3A3A3, 0xA5A5A5, 0xA7A7A7, 0xA9A9A9,
										0xABABAB, 0xADADAD, 0xAFAFAF, 0xB1B1B1,
										0xB3B3B3, 0xB5B5B5, 0xB6B6B6, 0xB8B8B8,
										0xBABABA, 0xBCBCBC, 0xBEBEBE, 0xC0C0C0,
										0xC2C2C2, 0xC4C4C4, 0xC6C6C6, 0xC8C8C8,
										0xCACACA, 0xCCCCCC, 0xCECECE, 0xCFCFCF,
										0xD1D1D1, 0xD3D3D3, 0xD5D5D5, 0xD7D7D7,
										0xD9D9D9, 0xDBDBDB, 0xDDDDDD, 0xDFDFDF,
										0xE1E1E1, 0xE3E3E3, 0xE4E4E4, 0xE6E6E6,
										0xE8E8E8, 0xEAEAEA, 0xECECEC, 0xEEEEEE,
										0xF0F0F0, 0xF2F2F2, 0xF4F4F4, 0xF6F6F6,
										0xF7F7F7, 0xF9F9F9, 0xFBFBFB, 0xFDFDFD}
								 };


	PSB_DEBUG_ENTRY("\n");

	/*reconfig lane configuration*/
	dsi_config->lane_count = 3;
	dsi_config->lane_config = MDFLD_DSI_DATA_LANE_3_1;
	dsi_config->enable_gamma_csc = ENABLE_GAMMA | ENABLE_CSC;
	/* This is for 400 mhz.  Set it to 0 for 800mhz */
	hw_ctx->cck_div = 1;
	hw_ctx->pll_bypass_mode = 0;

	hw_ctx->mipi_control = 0x00;
	hw_ctx->intr_en = 0xffffffff;
	hw_ctx->hs_tx_timeout = 0xffffff;
	hw_ctx->lp_rx_timeout = 0xffffff;
	hw_ctx->turn_around_timeout = 0x1f;
	hw_ctx->device_reset_timer = 0xffff;
	hw_ctx->high_low_switch_count = 0x20;
	hw_ctx->init_count = 0xf0;
	hw_ctx->eot_disable = 0x3;
	hw_ctx->lp_byteclk = 0x4;
	hw_ctx->clk_lane_switch_time_cnt = 0x20000E;
	hw_ctx->hs_ls_dbi_enable = 0x0;
	/* HW team suggested 1390 for bandwidth setting */
	hw_ctx->dbi_bw_ctrl = 1390;
	hw_ctx->dphy_param = 0x20124E1A;
	hw_ctx->dsi_func_prg = (0xa000 | dsi_config->lane_count);
	hw_ctx->mipi = TE_TRIGGER_GPIO_PIN;
	hw_ctx->mipi |= dsi_config->lane_config;

	if (dsi_config->enable_gamma_csc & ENABLE_CSC) {
		/* setting the tuned csc setting */
		drm_psb_enable_color_conversion = 1;
		mdfld_intel_crtc_set_color_conversion(dev, &csc);
	}

	if (dsi_config->enable_gamma_csc & ENABLE_GAMMA) {
		/* setting the tuned gamma setting */
		drm_psb_enable_gamma = 1;
		mdfld_intel_crtc_set_gamma(dev, &gamma);
	}

}

static
struct drm_display_mode *h8c7_cmd_get_config_mode(void)
{
	struct drm_display_mode *mode;

	PSB_DEBUG_ENTRY("\n");

	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
	if (!mode)
		return NULL;

	mode->htotal = 920;
	mode->hdisplay = 720;
	mode->hsync_start = 816;
	mode->hsync_end = 824;
	mode->vtotal = 1300;
	mode->vdisplay = 1280;
	mode->vsync_start = 1294;
	mode->vsync_end = 1296;
	mode->vrefresh = 60;
	mode->clock =  mode->vrefresh * mode->vtotal * mode->htotal / 1000;
	mode->type |= DRM_MODE_TYPE_PREFERRED;

	PSB_DEBUG_ENTRY("hdisplay is %d\n", mode->hdisplay);
	PSB_DEBUG_ENTRY("vdisplay is %d\n", mode->vdisplay);
	PSB_DEBUG_ENTRY("HSS is %d\n", mode->hsync_start);
	PSB_DEBUG_ENTRY("HSE is %d\n", mode->hsync_end);
	PSB_DEBUG_ENTRY("htotal is %d\n", mode->htotal);
	PSB_DEBUG_ENTRY("VSS is %d\n", mode->vsync_start);
	PSB_DEBUG_ENTRY("VSE is %d\n", mode->vsync_end);
	PSB_DEBUG_ENTRY("vtotal is %d\n", mode->vtotal);
	PSB_DEBUG_ENTRY("clock is %d\n", mode->clock);

	drm_mode_set_name(mode);
	drm_mode_set_crtcinfo(mode, 0);

	return mode;
}

static
int mdfld_dsi_h8c7_cmd_power_on(struct mdfld_dsi_config *dsi_config)
{

	struct mdfld_dsi_pkg_sender *sender =
		mdfld_dsi_get_pkg_sender(dsi_config);
	int err = 0;
	int enable_err, enabled = 0;

	PSB_DEBUG_ENTRY("\n");

	if (!sender) {
		DRM_ERROR("Failed to get DSI packet sender\n");
		return -EINVAL;
	}

	if (!IS_ERR(h8c7_regulator_status.regulator)) {

		if (!h8c7_regulator_status.h8c7_mmc2_on) {
			PSB_DEBUG_ENTRY("Before power on, regulator is %d\n",
			regulator_is_enabled(h8c7_regulator_status.regulator));
			PSB_DEBUG_ENTRY("Begin to power on\n");
			h8c7_regulator_status.h8c7_mmc2_on = true;
		} else {
			DRM_ERROR("power on several times without off\n");
		}

		enabled = regulator_is_enabled(h8c7_regulator_status.regulator);
		enable_err = regulator_enable(h8c7_regulator_status.regulator);
		if (enable_err < 0) {
			regulator_put(h8c7_regulator_status.regulator);
			DRM_ERROR("FATAL:enable h8c7 regulator error\n");
		}

		/* vemmc2 need 50ms delay due to stability
		** If already enabled, no need to wait for this delay.
		** This code isn't race proof but since in addition to
		** this panel driver only touch driver is enabling this
		** regulator and does it after this function has been
		** finished, this code works well enough for now.
		*/
		if (!enabled)
			msleep(50);
		PSB_DEBUG_ENTRY("After power on, regulator is %d\n",
			regulator_is_enabled(h8c7_regulator_status.regulator));
	}

	/*exit sleep */
	err = mdfld_dsi_send_dcs(sender,
		 exit_sleep_mode,
		 NULL,
		 0,
		 CMD_DATA_SRC_SYSTEM_MEM,
		 MDFLD_DSI_SEND_PACKAGE);
	if (err) {
		DRM_ERROR("faild to exit_sleep mode\n");
		goto power_err;
	}

	msleep(120);

	/*set tear on*/
	err = mdfld_dsi_send_dcs(sender,
		 set_tear_on,
		 NULL,
		 0,
		 CMD_DATA_SRC_SYSTEM_MEM,
		 MDFLD_DSI_SEND_PACKAGE);
	if (err) {
		DRM_ERROR("faild to set_tear_on mode\n");
		goto power_err;
	}

	/*turn on display*/
	err = mdfld_dsi_send_dcs(sender,
		 set_display_on,
		 NULL,
		 0,
		 CMD_DATA_SRC_SYSTEM_MEM,
		 MDFLD_DSI_SEND_PACKAGE);
	if (err) {
		DRM_ERROR("faild to set_display_on mode\n");
		goto power_err;
	}
	if (drm_psb_enable_cabc) {
		/* turn on cabc */
		h8c7_disable_cabc[1] = 0x2;
		mdfld_dsi_send_mcs_long_hs(sender, h8c7_disable_cabc,
					   sizeof(h8c7_disable_cabc), 0);
		mdelay(5);
		mdfld_dsi_send_gen_long_hs(sender, h8c7_mcs_protect_off, 4, 0);
		mdfld_dsi_send_mcs_long_hs(sender, h8c7_set_cabc_gain, 10, 0);
		mdfld_dsi_send_gen_long_hs(sender, h8c7_mcs_protect_on, 4, 0);
		DRM_INFO("%s enable h8c7 cabc\n", __func__);
	}
power_err:
	return err;
}

static int mdfld_dsi_h8c7_cmd_power_off(struct mdfld_dsi_config *dsi_config)
{
	struct mdfld_dsi_pkg_sender *sender =
		mdfld_dsi_get_pkg_sender(dsi_config);
	int err = 0;

	PSB_DEBUG_ENTRY("\n");

	if (!sender) {
		DRM_ERROR("Failed to get DSI packet sender\n");
		return -EINVAL;
	}

	/* turn off cabc */
	h8c7_disable_cabc[1] = 0x0;
	mdfld_dsi_send_mcs_long_lp(sender, h8c7_disable_cabc,
				   sizeof(h8c7_disable_cabc), 0);

	/*turn off backlight*/
	err = mdfld_dsi_send_mcs_long_lp(sender, h8c7_turn_off_backlight,
					 sizeof(h8c7_turn_off_backlight), 0);
	if (err) {
		DRM_ERROR("%s: failed to turn off backlight\n", __func__);
		goto out;
	}
	mdelay(1);


	/*turn off display */
	err = mdfld_dsi_send_dcs(sender,
		 set_display_off,
		 NULL,
		 0,
		 CMD_DATA_SRC_SYSTEM_MEM,
		 MDFLD_DSI_SEND_PACKAGE);
	if (err) {
		DRM_ERROR("sent set_display_off faild\n");
		goto out;
	}

	/*set tear off */
	err = mdfld_dsi_send_dcs(sender,
		 set_tear_off,
		 NULL,
		 0,
		 CMD_DATA_SRC_SYSTEM_MEM,
		 MDFLD_DSI_SEND_PACKAGE);
	if (err) {
		DRM_ERROR("sent set_tear_off faild\n");
		goto out;
	}

	/*Enter sleep mode */
	err = mdfld_dsi_send_dcs(sender,
			enter_sleep_mode,
			NULL,
			0,
			CMD_DATA_SRC_SYSTEM_MEM,
			MDFLD_DSI_SEND_PACKAGE);

	if (err) {
		DRM_ERROR("DCS 0x%x sent failed\n", enter_sleep_mode);
		goto out;
	}

	/**
	 * MIPI spec shows it must wait 5ms
	 * before sneding next command
	 */
	mdelay(5);

	/*enter deep standby mode*/
	err = mdfld_dsi_send_mcs_long_lp(sender, h8c7_mcs_protect_off, 4, 0);
	if (err) {
		DRM_ERROR("Failed to turn off protection\n");
		goto out;
	}

	err = mdfld_dsi_send_mcs_long_lp(sender, h8c7_set_power_dstb, 14, 0);
	if (err)
		DRM_ERROR("Failed to enter DSTB\n");
	mdelay(5);
	mdfld_dsi_send_mcs_long_lp(sender, h8c7_mcs_protect_on, 4, 0);

out:
	if (!IS_ERR(h8c7_regulator_status.regulator)) {
		if (h8c7_regulator_status.h8c7_mmc2_on) {
			h8c7_regulator_status.h8c7_mmc2_on = false;
			PSB_DEBUG_GENERAL("Begin to power off\n");
		} else
			DRM_ERROR("power off several times without on\n");
		regulator_disable(h8c7_regulator_status.regulator);
		PSB_DEBUG_GENERAL("After power off, regulator is %d\n",
			regulator_is_enabled(h8c7_regulator_status.regulator));
	}

	return err;
}

static
void h8c7_cmd_get_panel_info(int pipe, struct panel_info *pi)
{
	PSB_DEBUG_ENTRY("\n");

	if (pipe == 0) {
		pi->width_mm = PANEL_4DOT3_WIDTH;
		pi->height_mm = PANEL_4DOT3_HEIGHT;
	}
}

static
int mdfld_dsi_h8c7_cmd_detect(struct mdfld_dsi_config *dsi_config)
{
	int status;
	struct drm_device *dev = dsi_config->dev;
	struct mdfld_dsi_hw_registers *regs = &dsi_config->regs;
	u32 dpll_val, device_ready_val;
	int pipe = dsi_config->pipe;
	struct mdfld_dsi_pkg_sender *sender =
		mdfld_dsi_get_pkg_sender(dsi_config);

	PSB_DEBUG_ENTRY("\n");

	if (pipe == 0) {
		/*
		 * FIXME: WA to detect the panel connection status, and need to
		 * implement detection feature with get_power_mode DSI command.
		 */
		if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
					OSPM_UHB_FORCE_POWER_ON)) {
			DRM_ERROR("hw begin failed\n");
			return -EAGAIN;
		}

		dpll_val = REG_READ(regs->dpll_reg);
		device_ready_val = REG_READ(regs->device_ready_reg);
		if ((device_ready_val & DSI_DEVICE_READY) &&
		    (dpll_val & DPLL_VCO_ENABLE)) {
			dsi_config->dsi_hw_context.panel_on = true;
			mdfld_dsi_send_gen_long_hs(sender, h8c7_mcs_protect_off, 4, 0);
			mdfld_dsi_send_gen_long_hs(sender, h8c7_set_disp_reg, 13, 0);
			mdfld_dsi_send_gen_long_hs(sender, h8c7_mcs_protect_on, 4, 0);

		} else {
			dsi_config->dsi_hw_context.panel_on = false;
			DRM_INFO("%s: panel is not initialized!\n", __func__);
		}

		status = MDFLD_DSI_PANEL_CONNECTED;

		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
	} else {
		DRM_INFO("%s: do NOT support dual panel\n", __func__);
		status = MDFLD_DSI_PANEL_DISCONNECTED;
	}

	return status;
}
コード例 #30
0
ファイル: gi_renesas_cmd.c プロジェクト: DanBjorklund/ME302C
static void
gi_renesas_dsi_controller_init(struct mdfld_dsi_config *dsi_config)
{
	struct mdfld_dsi_hw_context *hw_ctx =
		&dsi_config->dsi_hw_context;
	struct drm_device *dev = dsi_config->dev;

	struct csc_setting csc = {	.pipe = 0,
					.type = CSC_REG_SETTING,
					.enable_state = true,
					.data_len = CSC_REG_COUNT,
					.data.csc_reg_data = {
						0xF510486, 0x27, 0x3F10FD0, 0x3E, 0x51000F, 0x39F}
				};
	struct gamma_setting gamma = {	.pipe = 0,
					.type = GAMMA_REG_SETTING,
					.enable_state = true,
					.data_len = GAMMA_10_BIT_TABLE_COUNT,
					.gamma_tableX100 = {
						0x000000, 0x010101, 0x020202, 0x030303,
						0x040404, 0x050505, 0x060606, 0x070807,
						0x080908, 0x0A0B0A, 0x0B0C0B, 0x0D0D0D,
						0x0E0F0E, 0x0F100F, 0x111211, 0x121312,
						0x141514, 0x151715, 0x171817, 0x191A19,
						0x1A1C1A, 0x1C1D1C, 0x1D1F1D, 0x1F211F,
						0x212221, 0x222422, 0x242624, 0x262726,
						0x272928, 0x292B29, 0x2B2D2B, 0x2D2F2D,
						0x2E302F, 0x303230, 0x323432, 0x343634,
						0x363836, 0x383A38, 0x393B39, 0x3B3D3B,
						0x3D3F3D, 0x3F413F, 0x414341, 0x434543,
						0x454745, 0x474947, 0x494B49, 0x4B4D4B,
						0x4C4F4D, 0x4E514F, 0x505351, 0x525552,
						0x545754, 0x565956, 0x585B58, 0x5A5D5A,
						0x5C5F5D, 0x5E615F, 0x606361, 0x636563,
						0x656765, 0x676967, 0x696B69, 0x6B6D6B,
						0x6D6F6D, 0x6F716F, 0x717371, 0x737573,
						0x757775, 0x777A78, 0x7A7C7A, 0x7C7E7C,
						0x7E807E, 0x808280, 0x828482, 0x848684,
						0x868887, 0x898B89, 0x8B8D8B, 0x8D8F8D,
						0x8F918F, 0x919391, 0x949594, 0x969896,
						0x989A98, 0x9A9C9A, 0x9D9E9D, 0x9FA09F,
						0xA1A3A1, 0xA3A5A3, 0xA5A7A6, 0xA8A9A8,
						0xAAACAA, 0xACAEAC, 0xAFB0AF, 0xB1B2B1,
						0xB3B5B3, 0xB5B7B5, 0xB8B9B8, 0xBABBBA,
						0xBCBEBC, 0xBFC0BF, 0xC1C2C1, 0xC3C5C3,
						0xC6C7C6, 0xC8C9C8, 0xCACBCA, 0xCDCECD,
						0xCFD0CF, 0xD1D2D1, 0xD4D5D4, 0xD6D7D6,
						0xD8D9D8, 0xDBDCDB, 0xDDDEDD, 0xE0E0E0,
						0xE2E3E2, 0xE4E5E4, 0xE7E7E7, 0xE9EAE9,
						0xECECEC, 0xEEEEEE, 0xF0F1F0, 0xF3F3F3,
						0xF5F5F5, 0xF8F8F8, 0xFAFAFA, 0xFDFDFD}
					};

	PSB_DEBUG_ENTRY("\n");

	dsi_config->lane_count = 1;
	dsi_config->lane_config = MDFLD_DSI_DATA_LANE_2_2;
	dsi_config->enable_gamma_csc = ENABLE_GAMMA | ENABLE_CSC;
	hw_ctx->pll_bypass_mode = 1;
	hw_ctx->cck_div = 1;
	hw_ctx->mipi_control = 0x00;
	hw_ctx->intr_en = 0xffffffff;
	hw_ctx->hs_tx_timeout = 0xffffff;
	hw_ctx->lp_rx_timeout = 0xffffff;
	hw_ctx->turn_around_timeout = 0x14;
	hw_ctx->device_reset_timer = 0xffff;
	hw_ctx->high_low_switch_count = 0x28;
	hw_ctx->init_count = 0xf0;
	hw_ctx->eot_disable = 0x2;
	hw_ctx->hs_ls_dbi_enable = 0x0;
	hw_ctx->lp_byteclk = 0x0;
	hw_ctx->clk_lane_switch_time_cnt = 0xa0014;
	hw_ctx->dphy_param = 0x150a600f;
	hw_ctx->dbi_bw_ctrl = 0x820;
	hw_ctx->mipi = PASS_FROM_SPHY_TO_AFE | TE_TRIGGER_GPIO_PIN;
	hw_ctx->mipi |= dsi_config->lane_config;
	/*set up func_prg*/
	hw_ctx->dsi_func_prg = (0xa000 | dsi_config->lane_count);

	if (dsi_config->enable_gamma_csc & ENABLE_CSC) {
		/* setting the tuned csc setting */
		drm_psb_enable_color_conversion = 1;
		mdfld_intel_crtc_set_color_conversion(dev, &csc);
	}

	if (dsi_config->enable_gamma_csc & ENABLE_GAMMA) {
		/* setting the tuned gamma setting */
		drm_psb_enable_gamma = 1;
		mdfld_intel_crtc_set_gamma(dev, &gamma);
	}
}

static
struct drm_display_mode *gi_renesas_cmd_get_config_mode(void)
{
	struct drm_display_mode *mode;

	PSB_DEBUG_ENTRY("\n");

	mode = kzalloc(sizeof(*mode), GFP_KERNEL);
	if (!mode)
		return NULL;

	mode->hdisplay = 320;
	mode->vdisplay = 480;
	/* HFP = 10, HSYNC = 10, HBP = 20 */
	mode->hsync_start = mode->hdisplay + 10;
	mode->hsync_end = mode->hsync_start + 10;
	mode->htotal = mode->hsync_end + 20;
	/* VFP = 10, VSYNC = 2, VBP = 20 */
	mode->vsync_start = mode->vdisplay + 10;
	mode->vsync_end = mode->vsync_start + 2;
	mode->vtotal = mode->vsync_end + 10;
	mode->vrefresh = 60;
	mode->clock = mode->vrefresh * mode->vtotal *
		mode->htotal / 1000;

	drm_mode_set_name(mode);
	drm_mode_set_crtcinfo(mode, 0);

	mode->type |= DRM_MODE_TYPE_PREFERRED;

	return mode;
}

static
int __gi_renesas_dsi_power_on(struct mdfld_dsi_config *dsi_config)
{
	struct drm_device *dev = dsi_config->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct mdfld_dsi_hw_registers *regs =
		&dsi_config->regs;
	struct mdfld_dsi_pkg_sender *sender =
		mdfld_dsi_get_pkg_sender(dsi_config);
	int err = 0;

	PSB_DEBUG_ENTRY("\n");

	if (!sender) {
		DRM_ERROR("Failed to get DSI packet sender\n");
		return -EINVAL;
	}

	if (drm_psb_enable_cabc) {
		/* enable cabc */
		gi_er61529_backlight_cntr_1[1] = 0x01;
		mdfld_dsi_send_gen_long_hs(sender, gi_er61529_mcs_protect_on, 2, 0);
		mdfld_dsi_send_gen_long_hs(sender, gi_er61529_backlight_cntr_1, 21, 0);
		mdfld_dsi_send_gen_long_hs(sender, gi_er61529_mcs_protect_off, 2, 0);
	}

	mdfld_dsi_send_gen_long_hs(sender, gi_er61529_mcs_protect_on, 2, 0);
	mdfld_dsi_send_gen_long_hs(sender, gi_er61529_backlight_cntr, 5, 0);
	mdfld_dsi_send_gen_long_hs(sender, gi_er61529_mcs_protect_off, 2, 0);
	mdfld_dsi_send_mcs_long_hs(sender, gi_er61529_exit_sleep_mode, 1, 0);
	mdelay(120);
	mdfld_dsi_send_mcs_long_hs(sender, gi_er61529_set_tear_on, 2, 0);
	mdfld_dsi_send_mcs_long_hs(sender, gi_er61529_dcs_set_display_on, 1, 0);

	return err;
}

static
int __gi_renesas_dsi_power_off(struct mdfld_dsi_config *dsi_config)
{
	struct mdfld_dsi_pkg_sender *sender =
		mdfld_dsi_get_pkg_sender(dsi_config);
	int err = 0;

	PSB_DEBUG_ENTRY("Turn off video mode TMD panel...\n");

	if (!sender) {
		DRM_ERROR("Failed to get DSI packet sender\n");
		return -EINVAL;
	}

	/* turn off display */
	err = mdfld_dsi_send_dcs(sender,
		 set_display_off,
		 NULL,
		 0,
		 CMD_DATA_SRC_SYSTEM_MEM,
		 MDFLD_DSI_SEND_PACKAGE);
	if (err) {
		DRM_ERROR("%s - sent set_display_off faild\n", __func__);
		goto power_err;
	}
	mdelay(70);

	/* set tear off display */
	err = mdfld_dsi_send_dcs(sender,
		 set_tear_off,
		 NULL,
		 0,
		 CMD_DATA_SRC_SYSTEM_MEM,
		 MDFLD_DSI_SEND_PACKAGE);
	if (err) {
		DRM_ERROR("%s - sent set_tear_off faild\n", __func__);
		goto power_err;
	}

	/* disable CABC */
	gi_er61529_backlight_cntr_1[1] = 0x00;
	mdfld_dsi_send_gen_long_hs(sender, gi_er61529_mcs_protect_on, 2, 0);
	mdfld_dsi_send_gen_long_hs(sender, gi_er61529_backlight_cntr_1, 21, 0);
	mdfld_dsi_send_gen_long_hs(sender, gi_er61529_mcs_protect_off, 2, 0);

	err =
	mdfld_dsi_send_mcs_long_hs(sender, gi_er61529_enter_sleep_mode, 1, 0);
	if (err) {
		DRM_ERROR("Enter sleep mode error\n");
		goto power_err;
	}
	mdelay(120);

	mdfld_dsi_send_gen_long_hs(sender, gi_er61529_mcs_protect_on, 2, 0);
	mdfld_dsi_send_gen_long_hs(sender, gi_er61529_mcs_lp_mode_cntr, 2, 0);
	mdfld_dsi_send_gen_long_hs(sender, gi_er61529_mcs_protect_off, 2, 0);

power_err:
	return err;
}

static
void gi_renesas_cmd_get_panel_info(int pipe, struct panel_info *pi)
{
	if (pipe == 0) {
		pi->width_mm = PANEL_3DOT47_WIDTH;
		pi->height_mm = PANEL_3DOT47_HEIGHT;
	}
}

static
int gi_renesas_dsi_cmd_detect(struct mdfld_dsi_config *dsi_config)
{
	struct drm_device *dev = dsi_config->dev;
	struct mdfld_dsi_hw_registers *regs = &dsi_config->regs;
	int status;
	int pipe = dsi_config->pipe;
	uint32_t dpll_val, device_ready_val;

	PSB_DEBUG_ENTRY("\n");

	if (pipe == 0) {
		if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
					OSPM_UHB_FORCE_POWER_ON)) {
			DRM_ERROR("hw begin failed\n");
			return -EAGAIN;
		}

		dpll_val = REG_READ(regs->dpll_reg);
		device_ready_val = REG_READ(regs->device_ready_reg);
		if ((device_ready_val & DSI_DEVICE_READY) &&
				(dpll_val & DPLL_VCO_ENABLE)) {
			dsi_config->dsi_hw_context.panel_on = true;
			status = MDFLD_DSI_PANEL_CONNECTED;
		} else {
			dsi_config->dsi_hw_context.panel_on = false;
			status = MDFLD_DSI_PANEL_DISCONNECTED;
			DRM_INFO("%s: do NOT support dual panel\n", __func__);
		}

		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
	} else {
		PSB_DEBUG_ENTRY("Only support single panel\n");
		status = MDFLD_DSI_PANEL_DISCONNECTED;
		dsi_config->dsi_hw_context.panel_on = 0;
	}

	return 0;
}

static
int gi_renesas_dsi_cmd_set_brightness(struct mdfld_dsi_config *dsi_config,
		int level)
{
	struct mdfld_dsi_pkg_sender *sender =
		mdfld_dsi_get_pkg_sender(dsi_config);
	u8 backlight_val;

	PSB_DEBUG_ENTRY("Set brightness level %d...\n", level);

	if (!sender) {
		DRM_ERROR("Failed to get DSI packet sender\n");
		return -EINVAL;
	}

	backlight_val = level * 255 / 100;
	gi_er61529_set_backlight[2] = backlight_val;

	mdfld_dsi_send_gen_long_hs(sender, gi_er61529_mcs_protect_on, 2, 0);
	mdfld_dsi_send_gen_long_hs(sender, gi_er61529_set_backlight, 5, 0);
	mdfld_dsi_send_gen_long_hs(sender, gi_er61529_mcs_protect_off, 2, 0);

	return 0;
}

static
int gi_renesas_dsi_panel_reset(struct mdfld_dsi_config *dsi_config)
{
	static int mipi_reset_gpio;
	int ret = 0;

	PSB_DEBUG_ENTRY("\n");

	if (mipi_reset_gpio == 0) {
		ret = get_gpio_by_name("mipi-reset");
		if (ret < 0) {
			DRM_ERROR("Faild to get panel reset gpio, " \
				  "use default reset pin\n");
			ret = 128;
		}

		mipi_reset_gpio = ret;

		ret = gpio_request(mipi_reset_gpio, "mipi_display");
		if (ret) {
			DRM_ERROR("Faild to request panel reset gpio\n");
			return -EINVAL;
		}

		gpio_direction_output(mipi_reset_gpio, 0);
	}

	gpio_set_value_cansleep(mipi_reset_gpio, 0);
	mdelay(11);

	gpio_set_value_cansleep(mipi_reset_gpio, 1);
	mdelay(20);

	return 0;
}


void gi_renesas_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs)
{
	p_funcs->get_config_mode = gi_renesas_cmd_get_config_mode;
	p_funcs->get_panel_info = gi_renesas_cmd_get_panel_info;
	p_funcs->reset = gi_renesas_dsi_panel_reset;
	p_funcs->drv_ic_init = gi_renesas_dbi_ic_init;
	p_funcs->dsi_controller_init = gi_renesas_dsi_controller_init;
	p_funcs->detect = gi_renesas_dsi_cmd_detect;
	p_funcs->set_brightness = gi_renesas_dsi_cmd_set_brightness;
	p_funcs->power_on = __gi_renesas_dsi_power_on;
	p_funcs->power_off = __gi_renesas_dsi_power_off;
}