blob: c578f997461ed052fb06645265d89b4b5fc720f8 [file] [log] [blame]
/*
* Copyright © 2011 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Jim Liu <jim.liu@intel.com>
*/
#include "android_hdmi.h"
#include "displayclass_interface.h"
#include "pwr_mgmt.h"
#define KEEP_UNUSED_CODE_S3D 0
/* Functions will be deleted after simulated on MDFLD_PLATFORM */
/* MRFLD_PLATFORM start */
#if KEEP_UNUSED_CODE_S3D
/**
* Set up the HDMI Vendor Specific InfoFrame Packet and send it to HDMI display
*
*/
static int mrfld_set_up_s3d_InfoFrame(struct drm_device *dev, enum
s3d_structure s3d_format)
{
u8 vsif[12] = { 0x81, 0x01, 0x06, 0x00, 0x03, 0x0c,
0x00, 0x40, 0x00, 0x00, 0x00, 0x00
};
u8 checksum = 0;
u32 *p_vsif = (u32 *) vsif;
u32 viddipctl_val = 0;
u32 buf_size = 0;
int i = 0;
PSB_DEBUG_ENTRY("s3d_format = %d\n", s3d_format);
/* Fill the 3d format in the HDMI Vendor Specific InfoFrame. */
vsif[8] = s3d_format << 4;
/* Get the buffer size in bytes */
buf_size = vsif[2] + 3;
/* Get the checksum byte. */
for (i = 0; i < buf_size; i++)
checksum += vsif[i];
checksum = 0xff - checksum + 1;
vsif[3] = checksum;
/* Wait for 2 VSyncs. */
mdelay(20); /* msleep(20); */
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/* Wait for 3 HSync. */
/* Disable the VS DIP type */
viddipctl_val = REG_READ(VIDEO_DIP_CTL);
viddipctl_val &= ~DIP_TYPE_VS;
REG_WRITE(VIDEO_DIP_CTL, viddipctl_val);
/* set the DIP buffer index to vendor specific. */
viddipctl_val &= ~(DIP_BUFF_INDX_MASK |
DIP_RAM_ADDR_MASK | DIP_TX_FREQ_MASK);
viddipctl_val |= DIP_BUFF_INDX_VS | EN_DIP;
REG_WRITE(VIDEO_DIP_CTL, viddipctl_val);
/* Get the buffer size in DWORD. */
buf_size = (buf_size + 3) / 4;
/* Write HDMI Vendor Specific InfoFrame. */
for (i = 0; i < buf_size; i++)
REG_WRITE(VIDEO_DIP_DATA, *(p_vsif++));
/* Enable the DIP type and transmission frequency. */
viddipctl_val |= DIP_TYPE_VS | DIP_TX_FREQ_2VSNC;
REG_WRITE(VIDEO_DIP_CTL, viddipctl_val);
return 0;
}
#endif /* if KEEP_UNUSED_CODE_S3D */
#if KEEP_UNUSED_CODE_S3D
/**
* Disable sending the HDMI Vendor Specific InfoFrame Packet.
*
*/
static int mrfld_disable_s3d_InfoFrame(struct drm_device *dev)
{
u32 viddipctl_val = 0;
PSB_DEBUG_ENTRY("\n");
/* Wait for 2 VSyncs. */
mdelay(20); /* msleep(20); */
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/* Wait for 3 HSync. */
/* Disable the VS DIP type */
viddipctl_val = REG_READ(VIDEO_DIP_CTL);
viddipctl_val &= ~DIP_TYPE_VS;
REG_WRITE(VIDEO_DIP_CTL, viddipctl_val);
return 0;
}
#endif /* if KEEP_UNUSED_CODE_S3D */
/**
* Disable the pipe, plane and pll.
*
* Note: FIXME need to modify PLL
*/
void mrfld_disable_crtc(struct drm_device *dev, int pipe, bool plane_d)
{
int dpll_reg = MRST_DPLL_A;
int dspcntr_reg = DSPACNTR;
int dspcntr_reg_d = DSPDCNTR;
int dspsurf_reg = DSPASURF;
int dspsurf_reg_d = DSPDSURF;
int pipeconf_reg = PIPEACONF;
u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
u32 temp;
PSB_DEBUG_ENTRY("pipe = %d\n", pipe);
#ifdef CONFIG_SUPPORT_MIPI
if (pipe != 1 && ((get_panel_type(dev, pipe) == JDI_7x12_VID) ||
(get_panel_type(dev, pipe) == CMI_7x12_VID)))
#else
if (pipe != 1)
#endif
return;
switch (pipe) {
case 0:
break;
case 1:
dpll_reg = MDFLD_DPLL_B;
dspcntr_reg = DSPBCNTR;
dspsurf_reg = DSPBSURF;
pipeconf_reg = PIPEBCONF;
break;
case 2:
dpll_reg = MRST_DPLL_A;
dspcntr_reg = DSPCCNTR;
dspsurf_reg = DSPCSURF;
pipeconf_reg = PIPECCONF;
gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
break;
default:
DRM_ERROR("Illegal Pipe Number. \n");
return;
}
if (pipe != 1)
mdfld_dsi_gen_fifo_ready(dev, gen_fifo_stat_reg,
HS_CTRL_FIFO_EMPTY |
HS_DATA_FIFO_EMPTY);
/* Disable display plane */
temp = REG_READ(dspcntr_reg);
if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
REG_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
/* Flush the plane changes */
REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
REG_READ(dspsurf_reg);
}
/* Disable display plane D. */
if (plane_d) {
temp = REG_READ(dspcntr_reg_d);
if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
REG_WRITE(dspcntr_reg_d, temp & ~DISPLAY_PLANE_ENABLE);
/* Flush the plane changes */
REG_WRITE(dspsurf_reg_d, REG_READ(dspsurf_reg_d));
REG_READ(dspsurf_reg_d);
}
}
/* Next, disable display pipes */
temp = REG_READ(pipeconf_reg);
if ((temp & PIPEACONF_ENABLE) != 0) {
temp &= ~PIPEACONF_ENABLE;
temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
REG_WRITE(pipeconf_reg, temp);
REG_READ(pipeconf_reg);
/* Wait for for the pipe disable to take effect. */
mdfldWaitForPipeDisable(dev, pipe);
}
/* Disable PLLs. */
}
void mofd_update_fifo_size(struct drm_device *dev, bool hdmi_on)
{
#ifdef CONFIG_SUPPORT_MIPI
struct drm_psb_private *dev_priv = dev->dev_private;
struct mdfld_dsi_config *dsi_config = dev_priv->dsi_configs[0];
struct mdfld_dsi_hw_context *ctx = NULL;
DRM_INFO("setting fifo size, hdmi_suspend: %d\n", hdmi_on);
if (!hdmi_on) {
/* no hdmi, 12KB for plane A D E F */
REG_WRITE(DSPARB2, 0x90180);
REG_WRITE(DSPARB, 0xc0300c0);
} else {
/* with hdmi, 10KB for plane A D E F; 8KB for plane B */
REG_WRITE(DSPARB2, 0x981c0);
REG_WRITE(DSPARB, 0x120480a0);
}
if (dsi_config) {
ctx = &dsi_config->dsi_hw_context;
ctx->dsparb = REG_READ(DSPARB);
ctx->dsparb2 = REG_READ(DSPARB2);
}
#else
if (hdmi_on) {
REG_WRITE(DDL1, 0x86868686);
REG_WRITE(DDL2, 0x86868686);
REG_WRITE(DDL3, 0x86);
REG_WRITE(DDL4, 0x8686);
/* FIXME: tune for HDMI only device */
/* with hdmi, 16KB for plane A B D */
REG_WRITE(DSPARB2, 0xc0300);
REG_WRITE(DSPARB, 0x20080100);
DRM_INFO("setting fifo size, arb2:0x%x, arb: 0x%x\n",
REG_READ(DSPARB2), REG_READ(DSPARB));
}
#endif
}
/**
* Sets the power management mode of crtc including the pll pipe and plane.
*
*/
static void mrfld_crtc_dpms(struct drm_crtc *crtc, int mode)
{
struct drm_device *dev = crtc->dev;
DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
int pipe = psb_intel_crtc->pipe;
int dpll_reg = MRST_DPLL_A;
int dspcntr_reg = DSPACNTR;
int dspbase_reg = MRST_DSPABASE;
int pipeconf_reg = PIPEACONF;
u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
u32 pipeconf = dev_priv->pipeconf;
u32 dspcntr = dev_priv->dspcntr;
#ifdef CONFIG_SUPPORT_MIPI
u32 pipestat_reg = PIPEASTAT;
u32 mipi_enable_reg = MIPIA_DEVICE_READY_REG;
#endif
u32 temp;
bool enabled;
u32 power_island = 0;
unsigned long irqflags;
struct android_hdmi_priv *hdmi_priv = dev_priv->hdmi_priv;
PSB_DEBUG_ENTRY("mode = %d, pipe = %d\n", mode, pipe);
#ifdef CONFIG_SUPPORT_MIPI
#ifndef CONFIG_SUPPORT_TOSHIBA_MIPI_DISPLAY
/**
* MIPI dpms
* NOTE: this path only works for TMD panel now. update it to
* support all MIPI panels later.
*/
if (pipe != 1 && (IS_MOFD(dev) ||
(get_panel_type(dev, pipe) == TMD_VID) ||
(get_panel_type(dev, pipe) == TMD_6X10_VID) ||
(get_panel_type(dev, pipe) == CMI_7x12_VID) ||
(get_panel_type(dev, pipe) == CMI_7x12_CMD) ||
(get_panel_type(dev, pipe) == SHARP_10x19_CMD) ||
(get_panel_type(dev, pipe) == SHARP_10x19_DUAL_CMD) ||
(get_panel_type(dev, pipe) == SHARP_25x16_CMD) ||
(get_panel_type(dev, pipe) == SDC_16x25_CMD) ||
(get_panel_type(dev, pipe) == SDC_25x16_CMD) ||
(get_panel_type(dev, pipe) == JDI_7x12_CMD) ||
(get_panel_type(dev, pipe) == JDI_7x12_VID) ||
(get_panel_type(dev, pipe) == SHARP_25x16_VID) ||
(get_panel_type(dev, pipe) == JDI_25x16_CMD) ||
(get_panel_type(dev, pipe) == JDI_25x16_VID))) {
return;
}
#endif
#else
if (pipe != 1)
return;
#endif
power_island = pipe_to_island(pipe);
if (!power_island_get(power_island))
return;
switch (pipe) {
#ifdef CONFIG_SUPPORT_MIPI
case 0:
break;
#endif
case 1:
dpll_reg = DPLL_B;
dspcntr_reg = DSPBCNTR;
dspbase_reg = MRST_DSPBBASE;
pipeconf_reg = PIPEBCONF;
pipeconf = dev_priv->pipeconf1;
dspcntr = dev_priv->dspcntr1;
if (IS_MDFLD(dev))
dpll_reg = MDFLD_DPLL_B;
break;
#ifdef CONFIG_SUPPORT_MIPI
case 2:
dpll_reg = MRST_DPLL_A;
dspcntr_reg = DSPCCNTR;
dspbase_reg = MDFLD_DSPCBASE;
pipeconf_reg = PIPECCONF;
pipestat_reg = PIPECSTAT;
pipeconf = dev_priv->pipeconf2;
dspcntr = dev_priv->dspcntr2;
gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
mipi_enable_reg = MIPIA_DEVICE_READY_REG + MIPIC_REG_OFFSET;
break;
#endif
default:
DRM_ERROR("Illegal Pipe Number.\n");
goto crtc_dpms_err;
}
/* XXX: When our outputs are all unaware of DPMS modes other than off
* and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
*/
switch (mode) {
case DRM_MODE_DPMS_ON:
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
DCLockMutex();
/* Enable the DPLL */
temp = REG_READ(dpll_reg);
if ((temp & DPLL_VCO_ENABLE) == 0) {
/* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
if (temp & MDFLD_PWR_GATE_EN) {
temp &= ~MDFLD_PWR_GATE_EN;
REG_WRITE(dpll_reg, temp);
/* FIXME_MDFLD PO - change 500 to 1 after PO */
udelay(500);
}
REG_WRITE(dpll_reg, temp);
REG_READ(dpll_reg);
/* FIXME_MDFLD PO - change 500 to 1 after PO */
udelay(500);
REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
REG_READ(dpll_reg);
#if 0 /* FIXME MRFLD */
/**
* wait for DSI PLL to lock
* NOTE: only need to poll status of pipe 0 and pipe 1,
* since both MIPI pipes share the same PLL.
*/
while ((pipe != 2) && (timeout < 20000)
&& !(REG_READ(pipeconf_reg) &
PIPECONF_DSIPLL_LOCK)) {
udelay(150);
timeout++;
}
#endif /* FIXME MRFLD */
}
/* Enable the plane */
temp = REG_READ(dspcntr_reg);
if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
REG_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
/* Flush the plane changes */
REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
}
/* Enable the pipe */
temp = REG_READ(pipeconf_reg);
if ((temp & PIPEACONF_ENABLE) == 0) {
REG_WRITE(pipeconf_reg, pipeconf);
/* Wait for for the pipe enable to take effect. */
mdfldWaitForPipeEnable(dev, pipe);
}
#ifdef CONFIG_SUPPORT_MIPI
/*workaround for sighting 3741701 Random X blank display */
/*perform w/a in video mode only on pipe A or C */
if ((pipe == 0 || pipe == 2) &&
(is_panel_vid_or_cmd(dev) == MDFLD_DSI_ENCODER_DPI)) {
REG_WRITE(pipestat_reg, REG_READ(pipestat_reg));
msleep(100);
if (PIPE_VBLANK_STATUS & REG_READ(pipestat_reg)) {
PSB_DEBUG_ENTRY("OK");
} else {
PSB_DEBUG_ENTRY("STUCK!!!!");
/*shutdown controller */
temp = REG_READ(dspcntr_reg);
REG_WRITE(dspcntr_reg,
temp & ~DISPLAY_PLANE_ENABLE);
REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
/*mdfld_dsi_dpi_shut_down(dev, pipe); */
REG_WRITE(0xb048, 1);
msleep(100);
temp = REG_READ(pipeconf_reg);
temp &= ~PIPEACONF_ENABLE;
REG_WRITE(pipeconf_reg, temp);
msleep(100); /*wait for pipe disable */
/*printk(KERN_ALERT "70008 is %x\n", REG_READ(0x70008));
printk(KERN_ALERT "b074 is %x\n", REG_READ(0xb074)); */
REG_WRITE(mipi_enable_reg, 0);
msleep(100);
PSB_DEBUG_ENTRY("70008 is %x\n",
REG_READ(0x70008));
PSB_DEBUG_ENTRY("b074 is %x\n",
REG_READ(0xb074));
REG_WRITE(0xb004, REG_READ(0xb004));
/* try to bring the controller back up again */
REG_WRITE(mipi_enable_reg, 1);
temp = REG_READ(dspcntr_reg);
REG_WRITE(dspcntr_reg,
temp | DISPLAY_PLANE_ENABLE);
REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
/*mdfld_dsi_dpi_turn_on(dev, pipe); */
REG_WRITE(0xb048, 2);
msleep(100);
temp = REG_READ(pipeconf_reg);
temp |= PIPEACONF_ENABLE;
REG_WRITE(pipeconf_reg, temp);
}
}
psb_intel_crtc_load_lut(crtc);
#endif
if ((pipe == 1) && hdmi_priv)
hdmi_priv->hdmi_suspended = false;
psb_enable_vblank(dev, pipe);
spin_lock_irqsave(&dev->vbl_lock, irqflags);
dev->vblank_enabled[pipe] = 1;
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
DCAttachPipe(pipe);
DC_MRFLD_onPowerOn(pipe);
DCUnLockMutex();
/* Give the overlay scaler a chance to enable
if it's on this pipe */
/* psb_intel_crtc_dpms_video(crtc, true); TODO */
break;
case DRM_MODE_DPMS_OFF:
DCLockMutex();
/* Give the overlay scaler a chance to disable
* if it's on this pipe */
/* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
if (pipe != 1)
mdfld_dsi_gen_fifo_ready(dev, gen_fifo_stat_reg,
HS_CTRL_FIFO_EMPTY |
HS_DATA_FIFO_EMPTY);
/* Disable the VGA plane that we never use */
REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
if (!(pipe == 1 && dev_priv->hdmi_first_boot)) {
/* Disable display plane */
temp = REG_READ(dspcntr_reg);
if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
REG_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
/* Flush the plane changes */
REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
REG_READ(dspbase_reg);
}
/* Next, disable display pipes */
temp = REG_READ(pipeconf_reg);
if ((temp & PIPEACONF_ENABLE) != 0) {
temp &= ~PIPEACONF_ENABLE;
temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
REG_WRITE(pipeconf_reg, temp);
REG_READ(pipeconf_reg);
/* Wait for for the pipe disable to take effect. */
mdfldWaitForPipeDisable(dev, pipe);
}
temp = REG_READ(dpll_reg);
if (temp & DPLL_VCO_ENABLE) {
if (((pipe != 1)
&& !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) &
PIPEACONF_ENABLE))
|| (pipe == 1)) {
temp &= ~(DPLL_VCO_ENABLE);
REG_WRITE(dpll_reg, temp);
REG_READ(dpll_reg);
/* Wait for the clocks to turn off. */
/* FIXME_MDFLD PO may need more delay */
udelay(500);
}
}
drm_handle_vblank(dev, pipe);
/* Turn off vsync interrupt. */
drm_vblank_off(dev, pipe);
}
if ((pipe == 1) && hdmi_priv)
hdmi_priv->hdmi_suspended = true;
if (IS_ANN(dev))
mofd_update_fifo_size(dev, false);
/* Make the pending flip request as completed. */
DCUnAttachPipe(pipe);
DC_MRFLD_onPowerOff(pipe);
DCUnLockMutex();
break;
}
enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
crtc_dpms_err:
power_island_put(power_island);
}
static int mrfld_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
int x, int y, struct drm_framebuffer *old_fb)
{
struct drm_device *dev = crtc->dev;
struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
struct drm_psb_private *dev_priv =
(struct drm_psb_private *)dev->dev_private;
#ifdef CONFIG_SUPPORT_MIPI
struct mdfld_dsi_config *dsi_config = NULL;
#endif
int pipe = psb_intel_crtc->pipe;
PSB_DEBUG_ENTRY("pipe = 0x%x\n", pipe);
#ifdef CONFIG_SUPPORT_MIPI
switch (pipe) {
case 0:
dsi_config = dev_priv->dsi_configs[0];
break;
case 1:
break;
case 2:
dsi_config = dev_priv->dsi_configs[1];
break;
default:
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
if (pipe != 1) {
int clk;
if (dsi_config->lane_count)
clk = adjusted_mode->clock / dsi_config->lane_count;
else
clk = adjusted_mode->clock;
mrfld_setup_pll(dev, pipe, clk);
return mdfld_crtc_dsi_mode_set(crtc, dsi_config, mode,
adjusted_mode, x, y, old_fb);
} else {
if (IS_ANN(dev))
mofd_update_fifo_size(dev, true);
android_hdmi_crtc_mode_set(crtc, mode, adjusted_mode,
x, y, old_fb);
return 0;
}
#else
if (pipe == 1) {
struct psb_fbdev *fbdev = NULL;
struct psb_framebuffer *psbfb = NULL;
struct fb_info *info = NULL;
if (dev_priv)
fbdev = dev_priv->fbdev;
if (fbdev)
psbfb = fbdev->pfb;
if (psbfb)
info = psbfb->fbdev;
if (IS_ANN(dev))
mofd_update_fifo_size(dev, true);
android_hdmi_crtc_mode_set(crtc, mode, adjusted_mode,
x, y, old_fb);
// clear init fb once driver set its own mode
if (info && info->screen_base &&
!dev_priv->hdmi_first_boot && dev_priv->um_start)
memset(info->screen_base, 0, info->screen_size);
}
return 0;
#endif
}
#if KEEP_UNUSED_CODE_S3D
/**
* Perform display 3D mode set to half line interleaving 3D display with two buffers.
*
* FIXME modify the following function with option to disable PLL or not.
*
* Function return value: 0 if error, 1 if success.
*/
int mrfld_s3d_flip_surf_addr(struct drm_device *dev, int pipe, struct
mrfld_s3d_flip *ps3d_flip)
{
/* register */
u32 dspsurf_reg = DSPASURF;
u32 dspsurf_reg_d = DSPDSURF;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
switch (pipe) {
case 0:
break;
case 1:
dspsurf_reg = DSPBSURF;
break;
case 2:
dspsurf_reg = DSPCSURF;
break;
default:
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
if (ps3d_flip->s3d_state & S3D_STATE_ENALBLED) {
REG_WRITE(dspsurf_reg, ps3d_flip->uiAddr_l);
REG_WRITE(dspsurf_reg_d, ps3d_flip->uiAddr_r);
} else {
REG_WRITE(dspsurf_reg, ps3d_flip->uiAddr_l);
}
return 1;
}
/*
extern void mdfld_dsi_tmd_drv_ic_init(struct mdfld_dsi_config *dsi_config,
int pipe);
*/
/**
* Perform display 3D mode set to half line interleaving 3D display with two buffers.
*
* FIXME modify the following function with option to disable PLL or not.
*/
int mrfld_s3d_to_line_interleave_half(struct drm_device *dev, int pipe, struct
mrfld_s3d_flip *ps3d_flip)
{
DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
struct mdfld_dsi_config *dsi_config = dev_priv->dsi_configs[0];
/* register */
u32 pipeconf_reg = PIPEACONF;
u32 dspcntr_reg = DSPACNTR;
u32 dspstride_reg = DSPASTRIDE;
u32 dsplinoff_reg = DSPALINOFF;
u32 dspsize_reg = DSPASIZE;
u32 dspsurf_reg = DSPASURF;
u32 mipi_reg = MIPI;
u32 dspcntr_reg_d = DSPDCNTR;
u32 dspstride_reg_d = DSPDSTRIDE;
u32 dsplinoff_reg_d = DSPDLINOFF;
u32 dspsize_reg_d = DSPDSIZE;
u32 dspsurf_reg_d = DSPDSURF;
/* values */
u32 pipeconf_val = 0;
u32 dspcntr_val = 0;
u32 dspsize_val = 0;
u32 mipi_val = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
switch (pipe) {
case 0:
break;
case 1:
DRM_ERROR("HDMI doesn't support line interleave half. \n");
return 0;
case 2:
dsi_config = dev_priv->dsi_configs[1];
pipeconf_reg = PIPECCONF;
dspcntr_reg = DSPCCNTR;
dspstride_reg = DSPCSTRIDE;
dsplinoff_reg = DSPCLINOFF;
dspsize_reg = DSPCSIZE;
dspsurf_reg = DSPCSURF;
mipi_reg = MIPI_C;
break;
default:
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspsize_val = REG_READ(dspsize_reg);
mipi_val = REG_READ(mipi_reg);
/* Disable pipe and port, don't disable the PLL. */
mrfld_disable_crtc(dev, pipe, true);
/* Set up line interleaving display 3D format. */
dspsize_val = (((dspsize_val & 0xFFFF0000) + 0x00010000) / 2 -
0x00010000) | (dspsize_val & 0x0000FFFF);
REG_WRITE(dspsize_reg, dspsize_val);
REG_WRITE(dspsize_reg_d, dspsize_val);
/* set up the frame buffer stride, offset and start. */
REG_WRITE(dspstride_reg, ps3d_flip->pitch_l);
REG_WRITE(dspstride_reg_d, ps3d_flip->pitch_r);
REG_WRITE(dsplinoff_reg, 0);
REG_WRITE(dsplinoff_reg_d, 0);
REG_WRITE(dspsurf_reg, ps3d_flip->uiAddr_l);
REG_WRITE(dspsurf_reg_d, ps3d_flip->uiAddr_r);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
if ((pipe == 0) || (pipe == 2)) {
/*set up mipi port related registers */
REG_WRITE(mipi_reg, mipi_val);
/*setup MIPI adapter + MIPI IP registers */
/* mdfld_dsi_controller_init(dsi_config, pipe); */
mdelay(20); /* msleep(20); */
/* re-init the panel */
dsi_config->drv_ic_inited = 0;
/* mdfld_dsi_tmd_drv_ic_init(dsi_config, pipe); */
}
/*enable the plane */
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
REG_WRITE(dspcntr_reg_d, dspcntr_val);
dspcntr_val |= S3D_SPRITE_ORDER_A_FIRST | S3D_SPRITE_INTERLEAVING_LINE;
REG_WRITE(dspcntr_reg, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
return 0;
}
/**
* Perform 2d mode set back from half line interleaving 3D display.
*
*/
int mrfld_s3d_from_line_interleave_half(struct drm_device *dev, int pipe, struct
mrfld_s3d_flip *ps3d_flip)
{
DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
struct mdfld_dsi_config *dsi_config = dev_priv->dsi_configs[0];
/* register */
u32 pipeconf_reg = PIPEACONF;
u32 dspcntr_reg = DSPACNTR;
u32 dspstride_reg = DSPASTRIDE;
u32 dsplinoff_reg = DSPALINOFF;
u32 dspsize_reg = DSPASIZE;
u32 dspsurf_reg = DSPASURF;
u32 mipi_reg = MIPI;
/* values */
u32 pipeconf_val = 0;
u32 dspcntr_val = 0;
u32 dspsize_val = 0;
u32 mipi_val = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
switch (pipe) {
case 0:
break;
case 1:
DRM_ERROR("HDMI doesn't support line interleave half. \n");
return 0;
case 2:
dsi_config = dev_priv->dsi_configs[1];
pipeconf_reg = PIPECCONF;
dspcntr_reg = DSPCCNTR;
dspstride_reg = DSPCSTRIDE;
dsplinoff_reg = DSPCLINOFF;
dspsize_reg = DSPCSIZE;
dspsurf_reg = DSPCSURF;
mipi_reg = MIPI_C;
DRM_ERROR("HDMI doesn't support line interleave half. \n");
return 0;
default:
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspsize_val = REG_READ(dspsize_reg);
mipi_val = REG_READ(mipi_reg);
/* Disable pipe and port, don't disable the PLL. */
mrfld_disable_crtc(dev, pipe, true);
/* restore to 2D display size. */
REG_WRITE(dspsize_reg, (((dspsize_val & 0xFFFF0000) + 0x00010000) * 2 -
0x00010000) | (dspsize_val & 0x0000FFFF));
/* set up the frame buffer stride, offset and start. */
REG_WRITE(dspstride_reg, ps3d_flip->pitch_l);
REG_WRITE(dsplinoff_reg, 0);
REG_WRITE(dspsurf_reg, ps3d_flip->uiAddr_l);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
if ((pipe == 0) || (pipe == 2)) {
/*set up mipi port related registers */
REG_WRITE(mipi_reg, mipi_val);
/*setup MIPI adapter + MIPI IP registers */
/* mdfld_dsi_controller_init(dsi_config, pipe); */
mdelay(20); /* msleep(20); */
/* re-init the panel */
dsi_config->drv_ic_inited = 0;
/* mdfld_dsi_tmd_drv_ic_init(dsi_config, pipe); */
}
/*enable the plane */
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
REG_WRITE(dspcntr_reg, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
return 0;
}
/**
* Perform display 3D mode set to line interleaving 3D display with two buffers.
*
* FIXME: Assume the 3D buffer is the same as display resolution. Will re-visit
* it for panel fitting mode.
* Set up the pll, two times 2D clock.
*/
int mrfld_s3d_to_line_interleave(struct drm_device *dev, int pipe, struct
mrfld_s3d_flip *ps3d_flip)
{
DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
struct mdfld_dsi_config *dsi_config = dev_priv->dsi_configs[0];
/* register */
u32 pipeconf_reg = PIPEACONF;
u32 pipesrc_reg = PIPEASRC;
u32 vtot_reg = VTOTAL_A;
u32 vblank_reg = VBLANK_A;
u32 vsync_reg = VSYNC_A;
u32 dspcntr_reg = DSPACNTR;
u32 dspstride_reg = DSPASTRIDE;
u32 dsplinoff_reg = DSPALINOFF;
u32 dspsize_reg = DSPASIZE;
u32 dspsurf_reg = DSPASURF;
u32 mipi_reg = MIPI;
u32 dspcntr_reg_d = DSPDCNTR;
u32 dspstride_reg_d = DSPDSTRIDE;
u32 dsplinoff_reg_d = DSPDLINOFF;
u32 dspsize_reg_d = DSPDSIZE;
u32 dspsurf_reg_d = DSPDSURF;
/* values */
u32 pipeconf_val = 0;
u32 pipesrc_val = 0;
u32 vtot_val = 0;
u32 vblank_val = 0;
u32 vsync_val = 0;
u32 dspcntr_val = 0;
u32 dspsize_val = 0;
u32 mipi_val = 0;
u32 temp = 0;
u32 temp1 = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
switch (pipe) {
case 0:
break;
case 1:
pipeconf_reg = PIPEBCONF;
pipesrc_reg = PIPEBSRC;
vtot_reg = VTOTAL_B;
vblank_reg = VBLANK_B;
vsync_reg = VSYNC_B;
dspcntr_reg = DSPBCNTR;
dspstride_reg = DSPBSTRIDE;
dsplinoff_reg = DSPBLINOFF;
dspsize_reg = DSPBSIZE;
dspsurf_reg = DSPBSURF;
break;
case 2:
dsi_config = dev_priv->dsi_configs[1];
pipeconf_reg = PIPECCONF;
pipesrc_reg = PIPECSRC;
vtot_reg = VTOTAL_C;
vblank_reg = VBLANK_C;
vsync_reg = VSYNC_C;
dspcntr_reg = DSPCCNTR;
dspstride_reg = DSPCSTRIDE;
dsplinoff_reg = DSPCLINOFF;
dspsize_reg = DSPCSIZE;
dspsurf_reg = DSPCSURF;
mipi_reg = MIPI_C;
break;
default:
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
pipesrc_val = REG_READ(pipesrc_reg);
vtot_val = REG_READ(vtot_reg);
vblank_val = REG_READ(vblank_reg);
vsync_val = REG_READ(vsync_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspsize_val = REG_READ(dspsize_reg);
mipi_val = REG_READ(mipi_reg);
/* Disable pipe and port. */
mrfld_disable_crtc(dev, pipe, true);
/* Set up line interleaving display 3D format. */
/* Get the 3D pipe source. */
REG_WRITE(pipesrc_reg, (((pipesrc_val & 0x0000ffff) + 1) * 2 - 1) |
(pipesrc_val & 0xFFFF0000));
/* Get the 3D Vactive and Vtotal. */
temp = ((vtot_val & 0x0000FFFF) + 1) * 2 - 1;
temp1 = ((vtot_val & 0xFFFF0000) + 0x00010000) * 2 - 0x00010000;
REG_WRITE(vtot_reg, temp1 | temp);
/* Get the 3D Vblank. */
temp = ((vblank_val & 0x0000FFFF) + 1) * 2 - 1;
temp1 = ((vblank_val & 0xFFFF0000) + 0x00010000) * 2 - 0x00010000;
REG_WRITE(vblank_reg, temp1 | temp);
/* Get the 3D Vsync */
temp = ((vsync_val & 0x0000FFFF) + 1) * 2 - 1;
temp1 = ((vsync_val & 0xFFFF0000) + 0x00010000) * 2 - 0x00010000;
REG_WRITE(vsync_reg, temp1 | temp);
/* set up plane related registers */
REG_WRITE(dspsize_reg_d, dspsize_val);
/* set up the frame buffer stride, offset and start. */
REG_WRITE(dspstride_reg, ps3d_flip->pitch_l);
REG_WRITE(dspstride_reg_d, ps3d_flip->pitch_r);
REG_WRITE(dsplinoff_reg, 0);
REG_WRITE(dsplinoff_reg_d, 0);
REG_WRITE(dspsurf_reg, ps3d_flip->uiAddr_l);
REG_WRITE(dspsurf_reg_d, ps3d_flip->uiAddr_r);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
if ((pipe == 0) || (pipe == 2)) {
/*set up mipi port related registers */
REG_WRITE(mipi_reg, mipi_val);
/*setup MIPI adapter + MIPI IP registers */
/* mdfld_dsi_controller_init(dsi_config, pipe); */
mdelay(20); /* msleep(20); */
/* re-init the panel */
dsi_config->drv_ic_inited = 0;
/* mdfld_dsi_tmd_drv_ic_init(dsi_config, pipe); */
}
/*enable the plane */
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
REG_WRITE(dspcntr_reg_d, dspcntr_val);
dspcntr_val |= S3D_SPRITE_ORDER_A_FIRST | S3D_SPRITE_INTERLEAVING_LINE;
REG_WRITE(dspcntr_reg, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
/* set up Vendor Specific InfoFrame for 3D format. */
if (pipe == 1)
mrfld_set_up_s3d_InfoFrame(dev, S3D_LINE_ALTERNATIVE);
return 0;
}
/**
* Perform 2d mode set back from line interleaving 3D display.
*
*/
int mrfld_s3d_from_line_interleave(struct drm_device *dev, int pipe, struct
mrfld_s3d_flip *ps3d_flip)
{
DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
struct mdfld_dsi_config *dsi_config = dev_priv->dsi_configs[0];
/* register */
u32 pipeconf_reg = PIPEACONF;
u32 pipesrc_reg = PIPEASRC;
u32 vtot_reg = VTOTAL_A;
u32 vblank_reg = VBLANK_A;
u32 vsync_reg = VSYNC_A;
u32 dspcntr_reg = DSPACNTR;
u32 dspstride_reg = DSPASTRIDE;
u32 dsplinoff_reg = DSPALINOFF;
u32 dspsize_reg = DSPASIZE;
u32 dspsurf_reg = DSPASURF;
u32 mipi_reg = MIPI;
/* values */
u32 pipeconf_val = 0;
u32 pipesrc_val = 0;
u32 vtot_val = 0;
u32 vblank_val = 0;
u32 vsync_val = 0;
u32 dspcntr_val = 0;
u32 dspsize_val = 0;
u32 mipi_val = 0;
u32 temp = 0;
u32 temp1 = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
switch (pipe) {
case 0:
break;
case 1:
pipeconf_reg = PIPEBCONF;
pipesrc_reg = PIPEBSRC;
vtot_reg = VTOTAL_B;
vblank_reg = VBLANK_B;
vsync_reg = VSYNC_B;
dspcntr_reg = DSPBCNTR;
dspstride_reg = DSPBSTRIDE;
dsplinoff_reg = DSPBLINOFF;
dspsize_reg = DSPBSIZE;
dspsurf_reg = DSPBSURF;
break;
case 2:
dsi_config = dev_priv->dsi_configs[1];
pipeconf_reg = PIPECCONF;
pipesrc_reg = PIPECSRC;
vtot_reg = VTOTAL_C;
vblank_reg = VBLANK_C;
vsync_reg = VSYNC_C;
pipeconf_reg = PIPECCONF;
dspcntr_reg = DSPCCNTR;
dspstride_reg = DSPCSTRIDE;
dsplinoff_reg = DSPCLINOFF;
dspsize_reg = DSPCSIZE;
dspsurf_reg = DSPCSURF;
mipi_reg = MIPI_C;
break;
default:
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
pipesrc_val = REG_READ(pipesrc_reg);
vtot_val = REG_READ(vtot_reg);
vblank_val = REG_READ(vblank_reg);
vsync_val = REG_READ(vsync_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspsize_val = REG_READ(dspsize_reg);
mipi_val = REG_READ(mipi_reg);
/* Disable pipe and port. */
mrfld_disable_crtc(dev, pipe, true);
/* Set up the pll, half of 3D clock. */
/* mrfld_setup_pll (dev, pipe, adjusted_mode->clock); */
/* set up pipe related registers */
/* Get the 2D pipe source. */
REG_WRITE(pipesrc_reg, (((pipesrc_val & 0x0000ffff) + 1) / 2 - 1) |
(pipesrc_val & 0xFFFF0000));
/* Get the 2D Vactive and Vtotal. */
temp = ((vtot_val & 0x0000FFFF) + 1) / 2 - 1;
temp1 = ((vtot_val & 0xFFFF0000) + 0x00010000) / 2 - 0x00010000;
REG_WRITE(vtot_reg, temp1 | temp);
/* Get the 2D Vblank. */
temp = ((vblank_val & 0x0000FFFF) + 1) / 2 - 1;
temp1 = ((vblank_val & 0xFFFF0000) + 0x00010000) / 2 - 0x00010000;
REG_WRITE(vblank_reg, temp1 | temp);
/* Get the 2D Vsync */
temp = ((vsync_val & 0x0000FFFF) + 1) / 2 - 1;
temp1 = ((vsync_val & 0xFFFF0000) + 0x00010000) / 2 - 0x00010000;
REG_WRITE(vsync_reg, temp1 | temp);
/* set up the frame buffer stride, offset and start. */
REG_WRITE(dspstride_reg, ps3d_flip->pitch_l);
REG_WRITE(dsplinoff_reg, 0);
REG_WRITE(dspsurf_reg, ps3d_flip->uiAddr_l);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
if ((pipe == 0) || (pipe == 2)) {
/*set up mipi port related registers */
REG_WRITE(mipi_reg, mipi_val);
/*setup MIPI adapter + MIPI IP registers */
/* mdfld_dsi_controller_init(dsi_config, pipe); */
mdelay(20); /* msleep(20); */
/* re-init the panel */
dsi_config->drv_ic_inited = 0;
/* mdfld_dsi_tmd_drv_ic_init(dsi_config, pipe); */
}
/*enable the plane */
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
REG_WRITE(dspcntr_reg, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
/* set up Vendor Specific InfoFrame for 3D format. */
if (pipe == 1)
mrfld_disable_s3d_InfoFrame(dev);
return 0;
}
/**
* Perform display 3D mode set to frame packing 3D display.
*
* FIXME: Assume the 3D buffer is the same as display resolution. Will re-visit
* it for panel fitting mode.
* Set up the pll, two times 2D clock.
*/
int mrfld_s3d_to_frame_packing(struct drm_device *dev, int pipe, struct
mrfld_s3d_flip *ps3d_flip)
{
/* register */
u32 pipeconf_reg = PIPEBCONF;
u32 pipesrc_reg = PIPEBSRC;
u32 vtot_reg = VTOTAL_B;
u32 vblank_reg = VBLANK_B;
u32 vsync_reg = VSYNC_B;
u32 dspcntr_reg = DSPBCNTR;
u32 dspstride_reg = DSPBSTRIDE;
u32 dsplinoff_reg = DSPBLINOFF;
u32 dspsize_reg = DSPBSIZE;
u32 dspsurf_reg = DSPBSURF;
u32 dspcntr_reg_d = DSPDCNTR;
u32 dspstride_reg_d = DSPDSTRIDE;
u32 dsplinoff_reg_d = DSPDLINOFF;
u32 dspsize_reg_d = DSPDSIZE;
u32 dspsurf_reg_d = DSPDSURF;
u32 dsppos_reg_d = DSPDPOS;
/* values */
u32 pipeconf_val = 0;
u32 pipesrc_val = 0;
u32 vtot_val = 0;
u32 vblank_val = 0;
u32 vsync_val = 0;
u32 dspcntr_val = 0;
u32 dspsize_val = 0;
u32 dsppos_val = 0;
u32 temp = 0;
u32 temp1 = 0;
u32 temp2 = 0;
u32 temp3 = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
if (pipe != 1) {
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
pipesrc_val = REG_READ(pipesrc_reg);
vtot_val = REG_READ(vtot_reg);
vblank_val = REG_READ(vblank_reg);
vsync_val = REG_READ(vsync_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspsize_val = REG_READ(dspsize_reg);
/* Disable pipe and port. */
mrfld_disable_crtc(dev, pipe, true);
/* Set up the pll, two times 2D clock. */
/* mrfld_setup_pll (dev, pipe, adjusted_mode->clock); */
/* Set up frame packing display 3D format. */
/* set up pipe related registers */
/* Get the Vblank and Vborder period. */
temp = ((vtot_val & 0xFFFF0000) >> 16) - (vtot_val & 0x0000FFFF);
/* Get the 3D pipe source. */
REG_WRITE(pipesrc_reg,
(((pipesrc_val & 0x0000ffff) + 1) * 2 + temp -
1) | (pipesrc_val & 0xFFFF0000));
dsppos_val = temp + (pipesrc_val & 0x0000ffff) + 1;
dsppos_val <<= 16;
/* Get the 3D Vactive. */
temp += ((vtot_val & 0x0000FFFF) + 1) * 2 - 1;
/* Get the 3D Vtotal. */
temp1 = ((vtot_val & 0xFFFF0000) + 0x00010000) * 2 - 0x00010000;
REG_WRITE(vtot_reg, temp1 | temp);
/* Get the 3D Vblank. */
temp2 = (vblank_val & 0x0000FFFF) - (vtot_val & 0x0000FFFF);
temp3 = (vtot_val & 0xFFFF0000) - (vblank_val & 0xFFFF0000);
REG_WRITE(vblank_reg, (temp1 - temp3) | (temp + temp2));
/* Get the 3D Vsync */
temp2 = (vsync_val & 0x0000FFFF) - (vtot_val & 0x0000FFFF);
temp3 = (vtot_val & 0xFFFF0000) - (vsync_val & 0xFFFF0000);
REG_WRITE(vsync_reg, (temp1 - temp3) | (temp + temp2));
/* set up plane related registers */
REG_WRITE(dspsize_reg_d, dspsize_val);
REG_WRITE(dsppos_reg_d, dsppos_val);
/* set up the frame buffer stride, offset and start. */
REG_WRITE(dspstride_reg, ps3d_flip->pitch_l);
REG_WRITE(dspstride_reg_d, ps3d_flip->pitch_r);
REG_WRITE(dsplinoff_reg, 0);
REG_WRITE(dsplinoff_reg_d, 0);
REG_WRITE(dspsurf_reg, ps3d_flip->uiAddr_l);
REG_WRITE(dspsurf_reg_d, ps3d_flip->uiAddr_r);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
/*enable the plane */
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
REG_WRITE(dspcntr_reg, dspcntr_val);
REG_WRITE(dspcntr_reg_d, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
/* set up Vendor Specific InfoFrame for 3D format. */
if (pipe == 1)
mrfld_set_up_s3d_InfoFrame(dev, S3D_FRAME_PACKING);
return 0;
}
/**
* Perform 2d mode set back from frame packing 3D display.
*
*/
int mrfld_s3d_from_frame_packing(struct drm_device *dev, int pipe, struct
mrfld_s3d_flip *ps3d_flip)
{
/* register */
u32 pipeconf_reg = PIPEBCONF;
u32 pipesrc_reg = PIPEBSRC;
u32 vtot_reg = VTOTAL_B;
u32 vblank_reg = VBLANK_B;
u32 vsync_reg = VSYNC_B;
u32 dspcntr_reg = DSPBCNTR;
u32 dspstride_reg = DSPBSTRIDE;
u32 dsplinoff_reg = DSPBLINOFF;
u32 dspsize_reg = DSPBSIZE;
u32 dspsurf_reg = DSPBSURF;
/* values */
u32 pipeconf_val = 0;
u32 pipesrc_val = 0;
u32 vtot_val = 0;
u32 vblank_val = 0;
u32 vsync_val = 0;
u32 dspcntr_val = 0;
u32 dspsize_val = 0;
u32 temp = 0;
u32 temp1 = 0;
u32 temp2 = 0;
u32 temp3 = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
if (pipe != 1) {
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
pipesrc_val = REG_READ(pipesrc_reg);
vtot_val = REG_READ(vtot_reg);
vblank_val = REG_READ(vblank_reg);
vsync_val = REG_READ(vsync_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspsize_val = REG_READ(dspsize_reg);
/* Disable pipe and port. */
mrfld_disable_crtc(dev, pipe, true);
/* Set up the pll, half of 3D clock. */
/* mrfld_setup_pll (dev, pipe, adjusted_mode->clock); */
/* set up pipe related registers */
/* Get the Vblank and Vborder period. */
temp = ((vtot_val & 0xFFFF0000) >> 16) - (vtot_val & 0x0000FFFF);
/* Get the 2D pipe source. */
temp1 = ((pipesrc_val & 0x0000ffff) + 1 - temp) / 2 - 1;
REG_WRITE(pipesrc_reg, temp1 | (pipesrc_val & 0xFFFF0000));
/* Get the 2D Vactive. */
temp = ((vtot_val & 0x0000FFFF) + 1 - temp) / 2 - 1;
/* Get the 2D Vtotal. */
temp1 = ((vtot_val & 0xFFFF0000) + 0x00010000) / 2 - 0x00010000;
REG_WRITE(vtot_reg, temp1 | temp);
/* Get the 2D Vblank. */
temp2 = (vblank_val & 0x0000FFFF) - (vtot_val & 0x0000FFFF);
temp3 = (vtot_val & 0xFFFF0000) - (vblank_val & 0xFFFF0000);
REG_WRITE(vblank_reg, (temp1 - temp3) | (temp + temp2));
/* Get the 3D Vsync */
temp2 = (vsync_val & 0x0000FFFF) - (vtot_val & 0x0000FFFF);
temp3 = (vtot_val & 0xFFFF0000) - (vsync_val & 0xFFFF0000);
REG_WRITE(vblank_reg, (temp1 - temp3) | (temp + temp2));
/* set up plane related registers */
/* set up the frame buffer stride, offset and start. */
REG_WRITE(dspstride_reg, ps3d_flip->pitch_l);
REG_WRITE(dsplinoff_reg, 0);
REG_WRITE(dspsurf_reg, ps3d_flip->uiAddr_l);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
/*enable the plane */
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
REG_WRITE(dspcntr_reg, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
/* set up Vendor Specific InfoFrame for 3D format. */
if (pipe == 1)
mrfld_disable_s3d_InfoFrame(dev);
return 0;
}
/**
* Perform display 3D mode set to top_and_bottom 3D display.
*
* FIXME: Assume the 3D buffer is the same as display resolution. Will re-visit
* it for panel fitting mode.
*/
int mrfld_s3d_to_top_and_bottom(struct drm_device *dev, int pipe, struct
mrfld_s3d_flip *ps3d_flip)
{
/* register */
u32 pipeconf_reg = PIPEBCONF;
u32 dspcntr_reg = DSPBCNTR;
u32 dspstride_reg = DSPBSTRIDE;
u32 dsplinoff_reg = DSPBLINOFF;
u32 dspsize_reg = DSPBSIZE;
u32 dspsurf_reg = DSPBSURF;
u32 dspcntr_reg_d = DSPDCNTR;
u32 dspstride_reg_d = DSPDSTRIDE;
u32 dsplinoff_reg_d = DSPDLINOFF;
u32 dspsize_reg_d = DSPDSIZE;
u32 dspsurf_reg_d = DSPDSURF;
u32 dsppos_reg_d = DSPDPOS;
/* values */
u32 pipeconf_val = 0;
u32 dspcntr_val = 0;
u32 dspsize_val = 0;
u32 dsppos_val = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
if (pipe != 1) {
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspsize_val = REG_READ(dspsize_reg);
/* Disable pipe and port, don't disable the PLL. */
mrfld_disable_crtc(dev, pipe, true);
/* set up plane related registers */
dsppos_val = ((dspsize_val & 0xFFFF0000) + 0x00010000) / 2;
dspsize_val = (((dspsize_val & 0xFFFF0000) + 0x00010000) / 2 -
0x00010000) | (dspsize_val & 0x0000FFFF);
REG_WRITE(dspsize_reg, dspsize_val);
REG_WRITE(dspsize_reg_d, dspsize_val);
REG_WRITE(dsppos_reg_d, dsppos_val);
/* set up the frame buffer stride, offset and start. */
REG_WRITE(dspstride_reg, ps3d_flip->pitch_l);
REG_WRITE(dspstride_reg_d, ps3d_flip->pitch_r);
REG_WRITE(dsplinoff_reg, 0);
REG_WRITE(dsplinoff_reg_d, 0);
REG_WRITE(dspsurf_reg, ps3d_flip->uiAddr_l);
REG_WRITE(dspsurf_reg_d, ps3d_flip->uiAddr_r);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
/*enable the plane */
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
REG_WRITE(dspcntr_reg, dspcntr_val);
REG_WRITE(dspcntr_reg_d, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
/* set up Vendor Specific InfoFrame for 3D format. */
if (pipe == 1)
mrfld_set_up_s3d_InfoFrame(dev, S3D_TOP_AND_BOTTOM);
return 0;
}
/**
* Perform 2d mode set back from top_and_bottom 3D display.
*
*/
int mrfld_s3d_from_top_and_bottom(struct drm_device *dev, int pipe, struct
mrfld_s3d_flip *ps3d_flip)
{
/* register */
u32 pipeconf_reg = PIPEBCONF;
u32 dspcntr_reg = DSPBCNTR;
u32 dspstride_reg = DSPBSTRIDE;
u32 dsplinoff_reg = DSPBLINOFF;
u32 dspsize_reg = DSPBSIZE;
u32 dspsurf_reg = DSPBSURF;
/* values */
u32 pipeconf_val = 0;
u32 dspcntr_val = 0;
u32 dspsize_val = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
if (pipe != 1) {
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspsize_val = REG_READ(dspsize_reg);
/* Disable pipe and port, don't disable the PLL. */
mrfld_disable_crtc(dev, pipe, true);
/* set up plane related registers */
dspsize_val = (((dspsize_val & 0xFFFF0000) + 0x00010000) * 2 -
0x00010000) | (dspsize_val & 0x0000FFFF);
REG_WRITE(dspsize_reg, dspsize_val);
/* set up plane related registers */
/* set up the frame buffer stride, offset and start. */
REG_WRITE(dspstride_reg, ps3d_flip->pitch_l);
REG_WRITE(dsplinoff_reg, 0);
REG_WRITE(dspsurf_reg, ps3d_flip->uiAddr_l);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
/*enable the plane */
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
REG_WRITE(dspcntr_reg, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
/* set up Vendor Specific InfoFrame for 3D format. */
if (pipe == 1)
mrfld_disable_s3d_InfoFrame(dev);
return 0;
}
/**
* Perform display 3D mode set to full side_by_side 3D display.
*
* FIXME: Assume the 3D buffer is the same as display resolution. Will re-visit
* it for panel fitting mode.
* Set up the pll, two times 2D clock.
*/
int mrfld_s3d_to_full_side_by_side(struct drm_device *dev, int pipe, struct
mrfld_s3d_flip *ps3d_flip)
{
/* register */
u32 pipeconf_reg = PIPEBCONF;
u32 pipesrc_reg = PIPEBSRC;
u32 htot_reg = HTOTAL_B;
u32 hblank_reg = HBLANK_B;
u32 hsync_reg = HSYNC_B;
u32 dspcntr_reg = DSPBCNTR;
u32 dspstride_reg = DSPBSTRIDE;
u32 dsplinoff_reg = DSPBLINOFF;
u32 dspsize_reg = DSPBSIZE;
u32 dspsurf_reg = DSPBSURF;
u32 dspcntr_reg_d = DSPDCNTR;
u32 dspstride_reg_d = DSPDSTRIDE;
u32 dsplinoff_reg_d = DSPDLINOFF;
u32 dspsize_reg_d = DSPDSIZE;
u32 dspsurf_reg_d = DSPDSURF;
u32 dsppos_reg_d = DSPDPOS;
/* values */
u32 pipeconf_val = 0;
u32 pipesrc_val = 0;
u32 htot_val = 0;
u32 hblank_val = 0;
u32 hsync_val = 0;
u32 dspcntr_val = 0;
u32 dspsize_val = 0;
u32 dsppos_val = 0;
u32 temp = 0;
u32 temp1 = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
if (pipe != 1) {
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
pipesrc_val = REG_READ(pipesrc_reg);
htot_val = REG_READ(htot_reg);
hblank_val = REG_READ(hblank_reg);
hsync_val = REG_READ(hsync_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspsize_val = REG_READ(dspsize_reg);
/* Disable pipe and port. */
mrfld_disable_crtc(dev, pipe, true);
/* Set up the pll, two times 2D clock. */
/* mrfld_setup_pll (dev, pipe, adjusted_mode->clock); */
/* Set up full side-by-side display 3D format. */
/* set up pipe related registers */
/* Get the 3D pipe source. */
REG_WRITE(pipesrc_reg, (pipesrc_val & 0x0000ffff) |
(((pipesrc_val & 0xFFFF0000) + 0x00010000) * 2 - 0x00010000));
/* Get the 3D Hactive and Htotal. */
temp = ((htot_val & 0x0000FFFF) + 1) * 2 - 1;
temp1 = ((htot_val & 0xFFFF0000) + 0x00010000) * 2 - 0x00010000;
REG_WRITE(htot_reg, temp1 | temp);
/* Get the 3D Hblank. */
temp = ((hblank_val & 0x0000FFFF) + 1) * 2 - 1;
temp1 = ((hblank_val & 0xFFFF0000) + 0x00010000) * 2 - 0x00010000;
REG_WRITE(hblank_reg, temp1 | temp);
/* Get the 3D Hsync */
temp = ((hsync_val & 0x0000FFFF) + 1) * 2 - 1;
temp1 = ((hsync_val & 0xFFFF0000) + 0x00010000) * 2 - 0x00010000;
REG_WRITE(hsync_reg, temp1 | temp);
/* set up plane related registers */
REG_WRITE(dspsize_reg_d, dspsize_val);
dsppos_val = (dspsize_val & 0x0000ffff) + 1;
REG_WRITE(dsppos_reg_d, dsppos_val);
/* set up the frame buffer stride, offset and start. */
REG_WRITE(dspstride_reg, ps3d_flip->pitch_l);
REG_WRITE(dspstride_reg_d, ps3d_flip->pitch_r);
REG_WRITE(dsplinoff_reg, 0);
REG_WRITE(dsplinoff_reg_d, 0);
REG_WRITE(dspsurf_reg, ps3d_flip->uiAddr_l);
REG_WRITE(dspsurf_reg_d, ps3d_flip->uiAddr_r);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
/*enable the plane */
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
REG_WRITE(dspcntr_reg, dspcntr_val);
REG_WRITE(dspcntr_reg_d, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
/* set up Vendor Specific InfoFrame for 3D format. */
if (pipe == 1)
mrfld_set_up_s3d_InfoFrame(dev, S3D_SIDE_BY_SIDE_FULL);
return 0;
}
/**
* Perform 2d mode set back from full side_by_side 3D display.
*
*/
int mrfld_s3d_from_full_side_by_side(struct drm_device *dev, int pipe, struct
mrfld_s3d_flip *ps3d_flip)
{
/* register */
u32 pipeconf_reg = PIPEBCONF;
u32 pipesrc_reg = PIPEBSRC;
u32 htot_reg = HTOTAL_B;
u32 hblank_reg = HBLANK_B;
u32 hsync_reg = HSYNC_B;
u32 dspcntr_reg = DSPBCNTR;
u32 dspstride_reg = DSPBSTRIDE;
u32 dsplinoff_reg = DSPBLINOFF;
u32 dspsize_reg = DSPBSIZE;
u32 dspsurf_reg = DSPBSURF;
/* values */
u32 pipeconf_val = 0;
u32 pipesrc_val = 0;
u32 htot_val = 0;
u32 hblank_val = 0;
u32 hsync_val = 0;
u32 dspcntr_val = 0;
u32 dspsize_val = 0;
u32 temp = 0;
u32 temp1 = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
if (pipe != 1) {
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
pipesrc_val = REG_READ(pipesrc_reg);
htot_val = REG_READ(htot_reg);
hblank_val = REG_READ(hblank_reg);
hsync_val = REG_READ(hsync_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspsize_val = REG_READ(dspsize_reg);
/* Disable pipe and port. */
mrfld_disable_crtc(dev, pipe, true);
/* Set up the pll, half of 3D clock. */
/* mrfld_setup_pll (dev, pipe, adjusted_mode->clock); */
/* set up pipe related registers */
/* Get the 2D pipe source. */
REG_WRITE(pipesrc_reg, (pipesrc_val & 0x0000ffff) |
(((pipesrc_val & 0xFFFF0000) + 0x00010000) / 2 - 0x00010000));
/* Get the 2D Hactive and Htotal. */
temp = ((htot_val & 0x0000FFFF) + 1) / 2 - 1;
temp1 = ((htot_val & 0xFFFF0000) + 0x00010000) / 2 - 0x00010000;
REG_WRITE(htot_reg, temp1 | temp);
/* Get the 2D Hblank. */
temp = ((hblank_val & 0x0000FFFF) + 1) / 2 - 1;
temp1 = ((hblank_val & 0xFFFF0000) + 0x00010000) / 2 - 0x00010000;
REG_WRITE(hblank_reg, temp1 | temp);
/* Get the 2D Hsync */
temp = ((hsync_val & 0x0000FFFF) + 1) / 2 - 1;
temp1 = ((hsync_val & 0xFFFF0000) + 0x00010000) / 2 - 0x00010000;
REG_WRITE(hsync_reg, temp1 | temp);
/* set up plane related registers */
/* set up the frame buffer stride, offset and start. */
REG_WRITE(dspstride_reg, ps3d_flip->pitch_l);
REG_WRITE(dsplinoff_reg, 0);
REG_WRITE(dspsurf_reg, ps3d_flip->uiAddr_l);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
/*enable the plane */
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
REG_WRITE(dspcntr_reg, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
/* set up Vendor Specific InfoFrame for 3D format. */
if (pipe == 1)
mrfld_disable_s3d_InfoFrame(dev);
return 0;
}
/**
* Perform display 3D mode set to half side_by_side 3D display.
*
* FIXME: Assume the 3D buffer is the same as display resolution. Will re-visit
* it for panel fitting mode.
*/
int mrfld_s3d_to_half_side_by_side(struct drm_device *dev, int pipe, struct
mrfld_s3d_flip *ps3d_flip)
{
/* register */
u32 pipeconf_reg = PIPEBCONF;
u32 dspcntr_reg = DSPBCNTR;
u32 dspstride_reg = DSPBSTRIDE;
u32 dsplinoff_reg = DSPBLINOFF;
u32 dspsize_reg = DSPBSIZE;
u32 dspsurf_reg = DSPBSURF;
u32 dspcntr_reg_d = DSPDCNTR;
u32 dspstride_reg_d = DSPDSTRIDE;
u32 dsplinoff_reg_d = DSPDLINOFF;
u32 dspsize_reg_d = DSPDSIZE;
u32 dspsurf_reg_d = DSPDSURF;
u32 dsppos_reg_d = DSPDPOS;
/* values */
u32 pipeconf_val = 0;
u32 dspcntr_val = 0;
u32 dspsize_val = 0;
u32 dsppos_val = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
if (pipe != 1) {
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspsize_val = REG_READ(dspsize_reg);
/* Disable pipe and port, don't disable the PLL. */
mrfld_disable_crtc(dev, pipe, true);
/* Set up half side-by-side display 3D format. */
/* set up plane related registers */
dsppos_val = ((dspsize_val & 0x0000ffff) + 1) / 2;
REG_WRITE(dsppos_reg_d, dsppos_val);
dspsize_val = (dspsize_val & 0xffff0000) | (((dspsize_val & 0x0000ffff)
+ 1) / 2 - 1);
REG_WRITE(dspsize_reg, dspsize_val);
REG_WRITE(dspsize_reg_d, dspsize_val);
/* set up the frame buffer stride, offset and start. */
REG_WRITE(dspstride_reg, ps3d_flip->pitch_l);
REG_WRITE(dspstride_reg_d, ps3d_flip->pitch_r);
REG_WRITE(dsplinoff_reg, 0);
REG_WRITE(dsplinoff_reg_d, 0);
REG_WRITE(dspsurf_reg, ps3d_flip->uiAddr_l);
REG_WRITE(dspsurf_reg_d, ps3d_flip->uiAddr_r);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
/*enable the plane */
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
REG_WRITE(dspcntr_reg, dspcntr_val);
REG_WRITE(dspcntr_reg_d, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
/* set up Vendor Specific InfoFrame for 3D format. */
if (pipe == 1)
mrfld_set_up_s3d_InfoFrame(dev, S3D_SIDE_BY_SIDE_HALF);
return 0;
}
/**
* Perform 2d mode set back from half side_by_side 3D display.
*
*/
int mrfld_s3d_from_half_side_by_side(struct drm_device *dev, int pipe, struct
mrfld_s3d_flip *ps3d_flip)
{
/* register */
u32 pipeconf_reg = PIPEBCONF;
u32 dspcntr_reg = DSPBCNTR;
u32 dspstride_reg = DSPBSTRIDE;
u32 dsplinoff_reg = DSPBLINOFF;
u32 dspsize_reg = DSPBSIZE;
u32 dspsurf_reg = DSPBSURF;
/* values */
u32 pipeconf_val = 0;
u32 dspcntr_val = 0;
u32 dspsize_val = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
if (pipe != 1) {
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspsize_val = REG_READ(dspsize_reg);
/* Disable pipe and port, don't disable the PLL. */
mrfld_disable_crtc(dev, pipe, true);
/* set up plane related registers */
dspsize_val = (dspsize_val & 0xffff0000) | (((dspsize_val & 0x0000ffff)
+ 1) * 2 - 1);
REG_WRITE(dspsize_reg, dspsize_val);
/* set up the frame buffer stride, offset and start. */
REG_WRITE(dspstride_reg, ps3d_flip->pitch_l);
REG_WRITE(dsplinoff_reg, 0);
REG_WRITE(dspsurf_reg, ps3d_flip->uiAddr_l);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
/*enable the plane */
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
REG_WRITE(dspcntr_reg, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
/* set up Vendor Specific InfoFrame for 3D format. */
if (pipe == 1)
mrfld_disable_s3d_InfoFrame(dev);
return 0;
}
/**
* Perform display 3D mode set to pixel alternative 3D display.
*
* FIXME: Assume the 3D buffer is the same as display resolution. Will re-visit
* it for panel fitting mode.
* Set up the pll, two times 2D clock.
*/
int mrfld_s3d_to_pixel_interleaving_full(struct drm_device *dev, int pipe, struct
mrfld_s3d_flip *ps3d_flip)
{
DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
struct mdfld_dsi_config *dsi_config = dev_priv->dsi_configs[0];
/* register */
u32 pipeconf_reg = PIPEACONF;
u32 pipesrc_reg = PIPEASRC;
u32 htot_reg = HTOTAL_A;
u32 hblank_reg = HBLANK_A;
u32 hsync_reg = HSYNC_A;
u32 dspcntr_reg = DSPACNTR;
u32 dspstride_reg = DSPASTRIDE;
u32 dsplinoff_reg = DSPALINOFF;
u32 dspsize_reg = DSPASIZE;
u32 dspsurf_reg = DSPASURF;
u32 mipi_reg = MIPI;
u32 dspcntr_reg_d = DSPDCNTR;
u32 dspstride_reg_d = DSPDSTRIDE;
u32 dsplinoff_reg_d = DSPDLINOFF;
u32 dspsize_reg_d = DSPDSIZE;
u32 dspsurf_reg_d = DSPDSURF;
/* values */
u32 pipeconf_val = 0;
u32 pipesrc_val = 0;
u32 htot_val = 0;
u32 hblank_val = 0;
u32 hsync_val = 0;
u32 dspcntr_val = 0;
u32 dspsize_val = 0;
u32 mipi_val = 0;
u32 temp = 0;
u32 temp1 = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
switch (pipe) {
case 0:
break;
case 1:
DRM_ERROR("HDMI doesn't support pixel interleave full. \n");
return 0;
case 2:
dsi_config = dev_priv->dsi_configs[1];
pipeconf_reg = PIPECCONF;
pipesrc_reg = PIPECSRC;
htot_reg = HTOTAL_C;
hblank_reg = HBLANK_C;
hsync_reg = HSYNC_C;
dspcntr_reg = DSPCCNTR;
dspstride_reg = DSPCSTRIDE;
dsplinoff_reg = DSPCLINOFF;
dspsize_reg = DSPCSIZE;
dspsurf_reg = DSPCSURF;
mipi_reg = MIPI_C;
break;
default:
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
pipesrc_val = REG_READ(pipesrc_reg);
htot_val = REG_READ(htot_reg);
hblank_val = REG_READ(hblank_reg);
hsync_val = REG_READ(hsync_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspsize_val = REG_READ(dspsize_reg);
mipi_val = REG_READ(mipi_reg);
/* Disable pipe and port. */
mrfld_disable_crtc(dev, pipe, true);
/* Set up the pll, two times 2D clock. */
/* mrfld_setup_pll (dev, pipe, adjusted_mode->clock); */
/* Set up full pixel interleaving display 3D format. */
/* set up pipe related registers */
/* Get the 3D pipe source. */
REG_WRITE(pipesrc_reg, (pipesrc_val & 0x0000ffff) |
(((pipesrc_val & 0xFFFF0000) + 0x00010000) * 2 - 0x00010000));
/* Get the 3D Hactive and Htotal. */
temp = ((htot_val & 0x0000FFFF) + 1) * 2 - 1;
temp1 = ((htot_val & 0xFFFF0000) + 0x00010000) * 2 - 0x00010000;
REG_WRITE(htot_reg, temp1 | temp);
/* Get the 3D Hblank. */
temp = ((hblank_val & 0x0000FFFF) + 1) * 2 - 1;
temp1 = ((hblank_val & 0xFFFF0000) + 0x00010000) * 2 - 0x00010000;
REG_WRITE(hblank_reg, temp1 | temp);
/* Get the 3D Hsync */
temp = ((hsync_val & 0x0000FFFF) + 1) * 2 - 1;
temp1 = ((hsync_val & 0xFFFF0000) + 0x00010000) * 2 - 0x00010000;
REG_WRITE(hsync_reg, temp1 | temp);
/* set up plane related registers */
REG_WRITE(dspsize_reg_d, dspsize_val);
/* set up the frame buffer stride, offset and start. */
REG_WRITE(dspstride_reg, ps3d_flip->pitch_l);
REG_WRITE(dspstride_reg_d, ps3d_flip->pitch_r);
REG_WRITE(dsplinoff_reg, 0);
REG_WRITE(dsplinoff_reg_d, 0);
REG_WRITE(dspsurf_reg, ps3d_flip->uiAddr_l);
REG_WRITE(dspsurf_reg_d, ps3d_flip->uiAddr_r);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
if ((pipe == 0) || (pipe == 2)) {
/*set up mipi port related registers */
REG_WRITE(mipi_reg, mipi_val);
/*setup MIPI adapter + MIPI IP registers */
/* mdfld_dsi_controller_init(dsi_config, pipe); */
mdelay(20); /* msleep(20); */
/* re-init the panel */
dsi_config->drv_ic_inited = 0;
/* mdfld_dsi_tmd_drv_ic_init(dsi_config, pipe); */
}
/*enable the plane */
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
REG_WRITE(dspcntr_reg_d, dspcntr_val);
dspcntr_val |= S3D_SPRITE_ORDER_A_FIRST | S3D_SPRITE_INTERLEAVING_PIXEL;
REG_WRITE(dspcntr_reg, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
return 0;
}
/**
* Perform display 2D mode set from pixel alternative 3D display.
*
*/
int mrfld_s3d_from_pixel_interleaving_full(struct drm_device *dev, int pipe, struct
mrfld_s3d_flip *ps3d_flip)
{
DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
struct mdfld_dsi_config *dsi_config = dev_priv->dsi_configs[0];
/* register */
u32 pipeconf_reg = PIPEACONF;
u32 pipesrc_reg = PIPEASRC;
u32 htot_reg = HTOTAL_A;
u32 hblank_reg = HBLANK_A;
u32 hsync_reg = HSYNC_A;
u32 dspcntr_reg = DSPACNTR;
u32 dspstride_reg = DSPASTRIDE;
u32 dsplinoff_reg = DSPALINOFF;
u32 dspsize_reg = DSPASIZE;
u32 dspsurf_reg = DSPASURF;
u32 mipi_reg = MIPI;
/* values */
u32 pipeconf_val = 0;
u32 pipesrc_val = 0;
u32 htot_val = 0;
u32 hblank_val = 0;
u32 hsync_val = 0;
u32 dspcntr_val = 0;
u32 dspsize_val = 0;
u32 mipi_val = 0;
u32 temp = 0;
u32 temp1 = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
switch (pipe) {
case 0:
break;
case 1:
DRM_ERROR("HDMI doesn't support pixel interleave full. \n");
return 0;
case 2:
dsi_config = dev_priv->dsi_configs[1];
pipeconf_reg = PIPECCONF;
pipesrc_reg = PIPECSRC;
htot_reg = HTOTAL_C;
hblank_reg = HBLANK_C;
hsync_reg = HSYNC_C;
dspcntr_reg = DSPCCNTR;
dspstride_reg = DSPCSTRIDE;
dsplinoff_reg = DSPCLINOFF;
dspsize_reg = DSPCSIZE;
dspsurf_reg = DSPCSURF;
mipi_reg = MIPI_C;
break;
default:
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
pipesrc_val = REG_READ(pipesrc_reg);
htot_val = REG_READ(htot_reg);
hblank_val = REG_READ(hblank_reg);
hsync_val = REG_READ(hsync_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspsize_val = REG_READ(dspsize_reg);
mipi_val = REG_READ(mipi_reg);
/* Disable pipe and port. */
mrfld_disable_crtc(dev, pipe, true);
/* Set up the pll, half of 3D clock. */
/* mrfld_setup_pll (dev, pipe, adjusted_mode->clock); */
/* set up pipe related registers */
/* Get the 2D pipe source. */
REG_WRITE(pipesrc_reg, (pipesrc_val & 0x0000ffff) |
(((pipesrc_val & 0xFFFF0000) + 0x00010000) / 2 - 0x00010000));
/* Get the 2D Hactive and Htotal. */
temp = ((htot_val & 0x0000FFFF) + 1) / 2 - 1;
temp1 = ((htot_val & 0xFFFF0000) + 0x00010000) / 2 - 0x00010000;
REG_WRITE(htot_reg, temp1 | temp);
/* Get the 2D Hblank. */
temp = ((hblank_val & 0x0000FFFF) + 1) / 2 - 1;
temp1 = ((hblank_val & 0xFFFF0000) + 0x00010000) / 2 - 0x00010000;
REG_WRITE(hblank_reg, temp1 | temp);
/* Get the 2D Hsync */
temp = ((hsync_val & 0x0000FFFF) + 1) / 2 - 1;
temp1 = ((hsync_val & 0xFFFF0000) + 0x00010000) / 2 - 0x00010000;
REG_WRITE(hsync_reg, temp1 | temp);
/* set up plane related registers */
/* set up the frame buffer stride, offset and start. */
REG_WRITE(dspstride_reg, ps3d_flip->pitch_l);
REG_WRITE(dsplinoff_reg, 0);
REG_WRITE(dspsurf_reg, ps3d_flip->uiAddr_l);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
if ((pipe == 0) || (pipe == 2)) {
/*set up mipi port related registers */
REG_WRITE(mipi_reg, mipi_val);
/*setup MIPI adapter + MIPI IP registers */
/* mdfld_dsi_controller_init(dsi_config, pipe); */
mdelay(20); /* msleep(20); */
/* re-init the panel */
dsi_config->drv_ic_inited = 0;
/* mdfld_dsi_tmd_drv_ic_init(dsi_config, pipe); */
}
/*enable the plane */
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
REG_WRITE(dspcntr_reg, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
return 0;
}
/**
* Perform display 3D mode set to pixel alternative 3D display with two
* half-width L & R frame buffers.
*
*/
int mrfld_s3d_to_pixel_interleaving_half(struct drm_device *dev, int pipe, struct
mrfld_s3d_flip *ps3d_flip)
{
DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
struct mdfld_dsi_config *dsi_config = dev_priv->dsi_configs[0];
/* register */
u32 pipeconf_reg = PIPEACONF;
u32 dspcntr_reg = DSPACNTR;
u32 dspstride_reg = DSPASTRIDE;
u32 dsplinoff_reg = DSPALINOFF;
u32 dspsize_reg = DSPASIZE;
u32 dspsurf_reg = DSPASURF;
u32 mipi_reg = MIPI;
u32 dspcntr_reg_d = DSPDCNTR;
u32 dspstride_reg_d = DSPDSTRIDE;
u32 dsplinoff_reg_d = DSPDLINOFF;
u32 dspsize_reg_d = DSPDSIZE;
u32 dspsurf_reg_d = DSPDSURF;
/* values */
u32 pipeconf_val = 0;
u32 dspcntr_val = 0;
u32 dspsize_val = 0;
u32 mipi_val = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
switch (pipe) {
case 0:
break;
case 1:
DRM_ERROR("HDMI doesn't support pixel interleave half. \n");
return 0;
case 2:
dsi_config = dev_priv->dsi_configs[1];
pipeconf_reg = PIPECCONF;
dspcntr_reg = DSPCCNTR;
dspstride_reg = DSPCSTRIDE;
dsplinoff_reg = DSPCLINOFF;
dspsize_reg = DSPCSIZE;
dspsurf_reg = DSPCSURF;
mipi_reg = MIPI_C;
break;
default:
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspsize_val = REG_READ(dspsize_reg);
mipi_val = REG_READ(mipi_reg);
/* Disable pipe and port, don't disable the PLL. */
mrfld_disable_crtc(dev, pipe, true);
/* Set up half pixel interleaving display 3D format. */
/* set up plane related registers */
dspsize_val = (dspsize_val & 0xFFFF0000) | (((dspsize_val & 0x0000FFFF)
+ 1) / 2 - 1);
REG_WRITE(dspsize_reg, dspsize_val);
REG_WRITE(dspsize_reg_d, dspsize_val);
/* set up the frame buffer stride, offset and start. */
REG_WRITE(dspstride_reg, ps3d_flip->pitch_l);
REG_WRITE(dspstride_reg_d, ps3d_flip->pitch_r);
REG_WRITE(dsplinoff_reg, 0);
REG_WRITE(dsplinoff_reg_d, 0);
REG_WRITE(dspsurf_reg, ps3d_flip->uiAddr_l);
REG_WRITE(dspsurf_reg_d, ps3d_flip->uiAddr_r);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
if ((pipe == 0) || (pipe == 2)) {
/*set up mipi port related registers */
REG_WRITE(mipi_reg, mipi_val);
/*setup MIPI adapter + MIPI IP registers */
/* mdfld_dsi_controller_init(dsi_config, pipe); */
mdelay(20); /* msleep(20); */
/* re-init the panel */
dsi_config->drv_ic_inited = 0;
/* mdfld_dsi_tmd_drv_ic_init(dsi_config, pipe); */
}
/*enable the plane */
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
REG_WRITE(dspcntr_reg_d, dspcntr_val);
dspcntr_val |= S3D_SPRITE_ORDER_A_FIRST | S3D_SPRITE_INTERLEAVING_PIXEL;
REG_WRITE(dspcntr_reg, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
return 0;
}
/**
* Perform display 2D mode set from pixel alternative 3D display with two
* half-width L & R frame buffers.
*
*/
int mrfld_s3d_from_pixel_interleaving_half(struct drm_device *dev, int pipe, struct
mrfld_s3d_flip *ps3d_flip)
{
DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
struct mdfld_dsi_config *dsi_config = dev_priv->dsi_configs[0];
/* register */
u32 pipeconf_reg = PIPEACONF;
u32 dspcntr_reg = DSPACNTR;
u32 dspstride_reg = DSPASTRIDE;
u32 dsplinoff_reg = DSPALINOFF;
u32 dspsize_reg = DSPASIZE;
u32 dspsurf_reg = DSPASURF;
u32 mipi_reg = MIPI;
/* values */
u32 pipeconf_val = 0;
u32 dspcntr_val = 0;
u32 dspsize_val = 0;
u32 mipi_val = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
switch (pipe) {
case 0:
break;
case 1:
DRM_ERROR("HDMI doesn't support pixel interleave half. \n");
return 0;
case 2:
dsi_config = dev_priv->dsi_configs[1];
pipeconf_reg = PIPECCONF;
dspcntr_reg = DSPCCNTR;
dspstride_reg = DSPCSTRIDE;
dsplinoff_reg = DSPCLINOFF;
dspsize_reg = DSPCSIZE;
dspsurf_reg = DSPCSURF;
mipi_reg = MIPI_C;
break;
default:
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspsize_val = REG_READ(dspsize_reg);
mipi_val = REG_READ(mipi_reg);
/* Disable pipe and port, don't disable the PLL. */
mrfld_disable_crtc(dev, pipe, true);
/* set up plane related registers */
dspsize_val = (dspsize_val & 0xFFFF0000) | (((dspsize_val & 0x0000FFFF)
+ 1) * 2 - 1);
REG_WRITE(dspsize_reg, dspsize_val);
/* set up the frame buffer stride, offset and start. */
REG_WRITE(dspstride_reg, ps3d_flip->pitch_l);
REG_WRITE(dsplinoff_reg, 0);
REG_WRITE(dspsurf_reg, ps3d_flip->uiAddr_l);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
if ((pipe == 0) || (pipe == 2)) {
/*set up mipi port related registers */
REG_WRITE(mipi_reg, mipi_val);
/*setup MIPI adapter + MIPI IP registers */
/* mdfld_dsi_controller_init(dsi_config, pipe); */
mdelay(20); /* msleep(20); */
/* re-init the panel */
dsi_config->drv_ic_inited = 0;
/* mdfld_dsi_tmd_drv_ic_init(dsi_config, pipe); */
}
/*enable the plane */
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
REG_WRITE(dspcntr_reg, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
return 0;
}
/**
* Check if the DSI display supports S3D. If so, report supported S3D formats
*
*/
int mrfld_dsi_s3d_query(struct drm_device *dev, struct drm_psb_s3d_query
*s3d_query)
{
DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
struct mdfld_dsi_config *dsi_config = dev_priv->dsi_configs[0];
uint32_t s3d_display_type = s3d_query->s3d_display_type;
switch (s3d_display_type) {
case S3D_MIPIA_DISPLAY:
break;
case S3D_MIPIC_DISPLAY:
dsi_config = dev_priv->dsi_configs[1];
break;
default:
DRM_ERROR("invalid parameters. \n");
return -EINVAL;
}
if (dsi_config->s3d_format) {
s3d_query->is_s3d_supported = 1;
s3d_query->s3d_format = dsi_config->s3d_format;
}
return 0;
}
/**
* Check if the display supports S3D. If so, report supported S3D formats.
*
*/
int mrfld_s3d_query(struct drm_device *dev, struct drm_psb_s3d_query
*s3d_query)
{
uint32_t s3d_display_type = s3d_query->s3d_display_type;
switch (s3d_display_type) {
case S3D_MIPIA_DISPLAY:
case S3D_MIPIC_DISPLAY:
return mrfld_dsi_s3d_query(dev, s3d_query);
case S3D_HDMI_DISPLAY:
return mrfld_hdmi_s3d_query(dev, s3d_query);
default:
DRM_ERROR("invalid parameters. \n");
return -EINVAL;
}
}
#endif /* if KEEP_UNUSED_CODE_S3D */
#if 0
/**
* Perform display 3D mode set.
*
*/
static int mrfld_s3d_crtc_mode_set(struct drm_crtc *crtc,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode,
int x, int y, struct drm_framebuffer *old_fb)
{
struct drm_device *dev = crtc->dev;
struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
int pipe = psb_intel_crtc->pipe;
u32 dspcntr_reg = DSPACNTR;
u32 pipeconf_reg = PIPEACONF;
u32 htot_reg = HTOTAL_A;
u32 hblank_reg = HBLANK_A;
u32 hsync_reg = HSYNC_A;
u32 vtot_reg = VTOTAL_A;
u32 vblank_reg = VBLANK_A;
u32 vsync_reg = VSYNC_A;
u32 dspsize_reg = DSPASIZE;
u32 dsppos_reg = DSPAPOS;
u32 pipesrc_reg = PIPEASRC;
u32 *pipeconf = &dev_priv->pipeconf;
u32 *dspcntr = &dev_priv->dspcntr;
struct drm_mode_config *mode_config = &dev->mode_config;
struct psb_intel_output *psb_intel_output = NULL;
uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
struct drm_encoder *encoder;
struct drm_connector *connector;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
switch (pipe) {
case 0:
break;
case 1:
dspcntr_reg = DSPBCNTR;
pipeconf_reg = PIPEBCONF;
htot_reg = HTOTAL_B;
hblank_reg = HBLANK_B;
hsync_reg = HSYNC_B;
vtot_reg = VTOTAL_B;
vblank_reg = VBLANK_B;
vsync_reg = VSYNC_B;
dspsize_reg = DSPBSIZE;
dsppos_reg = DSPBPOS;
pipesrc_reg = PIPEBSRC;
pipeconf = &dev_priv->pipeconf1;
dspcntr = &dev_priv->dspcntr1;
break;
case 2:
dspcntr_reg = DSPCCNTR;
pipeconf_reg = PIPECCONF;
htot_reg = HTOTAL_C;
hblank_reg = HBLANK_C;
hsync_reg = HSYNC_C;
vtot_reg = VTOTAL_C;
vblank_reg = VBLANK_C;
vsync_reg = VSYNC_C;
dspsize_reg = DSPCSIZE;
dsppos_reg = DSPCPOS;
pipesrc_reg = PIPECSRC;
pipeconf = &dev_priv->pipeconf2;
dspcntr = &dev_priv->dspcntr2;
break;
default:
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
memcpy(&psb_intel_crtc->saved_mode, mode,
sizeof(struct drm_display_mode));
memcpy(&psb_intel_crtc->saved_adjusted_mode, adjusted_mode,
sizeof(struct drm_display_mode));
list_for_each_entry(connector, &mode_config->connector_list, head) {
if (!connector)
continue;
encoder = connector->encoder;
if (!encoder)
continue;
if (encoder->crtc != crtc)
continue;
psb_intel_output = to_psb_intel_output(connector);
PSB_DEBUG_ENTRY("output->type = 0x%x \n",
psb_intel_output->type);
}
/* Disable the panel fitter if it was on our pipe */
if (psb_intel_panel_fitter_pipe(dev) == pipe)
REG_WRITE(PFIT_CONTROL, 0);
/* pipesrc and dspsize control the size that is scaled from,
* which should always be the user's requested size.
*/
if (pipe == 1) {
/* FIXME: To make HDMI display with 864x480 (TPO), 480x864 (PYR) or 480x854 (TMD), set the sprite
* width/height and souce image size registers with the adjusted mode for pipe B. */
/* The defined sprite rectangle must always be completely contained within the displayable
* area of the screen image (frame buffer). */
REG_WRITE(dspsize_reg,
((MIN
(mode->crtc_vdisplay,
adjusted_mode->crtc_vdisplay) - 1) << 16)
|
(MIN
(mode->crtc_hdisplay,
adjusted_mode->crtc_hdisplay) - 1));
/* Set the CRTC with encoder mode. */
REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16)
| (mode->crtc_vdisplay - 1));
} else {
REG_WRITE(dspsize_reg,
((mode->crtc_vdisplay -
1) << 16) | (mode->crtc_hdisplay - 1));
REG_WRITE(pipesrc_reg,
((mode->crtc_hdisplay -
1) << 16) | (mode->crtc_vdisplay - 1));
}
REG_WRITE(dsppos_reg, 0);
if (psb_intel_output)
drm_object_property_get_value(&psb_intel_output->base->base,
dev->
mode_config.scaling_mode_property,
&scalingType);
if (scalingType == DRM_MODE_SCALE_NO_SCALE) {
/*Moorestown doesn't have register support for centering so we need to
mess with the h/vblank and h/vsync start and ends to get centering */
int offsetX = 0, offsetY = 0;
offsetX =
(adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2;
offsetY =
(adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2;
REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) |
((adjusted_mode->crtc_htotal - 1) << 16));
REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) |
((adjusted_mode->crtc_vtotal - 1) << 16));
REG_WRITE(hblank_reg,
(adjusted_mode->crtc_hblank_start - offsetX -
1) | ((adjusted_mode->crtc_hblank_end - offsetX -
1) << 16));
REG_WRITE(hsync_reg,
(adjusted_mode->crtc_hsync_start - offsetX -
1) | ((adjusted_mode->crtc_hsync_end - offsetX -
1) << 16));
REG_WRITE(vblank_reg,
(adjusted_mode->crtc_vblank_start - offsetY -
1) | ((adjusted_mode->crtc_vblank_end - offsetY -
1) << 16));
REG_WRITE(vsync_reg,
(adjusted_mode->crtc_vsync_start - offsetY -
1) | ((adjusted_mode->crtc_vsync_end - offsetY -
1) << 16));
} else {
REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
((adjusted_mode->crtc_htotal - 1) << 16));
REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
((adjusted_mode->crtc_vtotal - 1) << 16));
REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
((adjusted_mode->crtc_hblank_end - 1) << 16));
REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
((adjusted_mode->crtc_hsync_end - 1) << 16));
REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
((adjusted_mode->crtc_vblank_end - 1) << 16));
REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
((adjusted_mode->crtc_vsync_end - 1) << 16));
}
/* Flush the plane changes */
{
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
crtc_funcs->mode_set_base(crtc, x, y, old_fb);
}
/* setup pipeconf */
*pipeconf = PIPEACONF_ENABLE;
/* Set up the display plane register */
*dspcntr = REG_READ(dspcntr_reg);
*dspcntr |= pipe << DISPPLANE_SEL_PIPE_POS;
*dspcntr |= DISPLAY_PLANE_ENABLE;
mrfld_setup_pll(dev, pipe, adjusted_mode->clock);
if (pipe != 1)
goto mrst_crtc_mode_set_exit;
REG_WRITE(pipeconf_reg, *pipeconf);
REG_READ(pipeconf_reg);
REG_WRITE(dspcntr_reg, *dspcntr);
psb_intel_wait_for_vblank(dev);
mrst_crtc_mode_set_exit:
return 0;
}
/**
* Perform display 3D mode set from half Top-and-Bottom to half Top-and-Bottom 3D display.
*
*/
static int mrfld_s3d_half_top_and_bottom(struct drm_device *dev, int pipe)
{
DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
/* regester */
u32 dspsurf_reg = DSPASURF;
/* values */
u32 dspsurf_val = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x\n", pipe);
dspsurf_val = REG_READ(dspsurf_reg);
/* need to figure out the start. */
REG_WRITE(dspsurf_reg, dspsurf_val);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
/* set up Vendor Specific InfoFrame for 3D format. */
if (pipe == 1)
mrfld_set_up_s3d_InfoFrame(dev, S3D_TOP_AND_BOTTOM);
return 0;
}
/**
* Perform display 3D mode set from two full source inputs to line
* interleaving 3D display.
*
*/
static int mrfld_s3d_line_interleaving(struct drm_device *dev, int pipe)
{
DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
/* regester */
u32 pipeconf_reg = PIPEBCONF;
u32 pipesrc_reg = PIPEBSRC;
u32 vtot_reg = VTOTAL_B;
u32 vblank_reg = VBLANK_B;
u32 vsync_reg = VSYNC_B;
u32 dspcntr_reg = DSPBCNTR;
u32 dspstride_reg = DSPBSTRIDE;
u32 dsplinoff_reg = DSPBLINOFF;
u32 dspsize_reg = DSPBSIZE;
u32 dspsurf_reg = DSPBSURF;
u32 dspcntr_reg_d = DSPDCNTR;
u32 dspstride_reg_d = DSPDSTRIDE;
u32 dsplinoff_reg_d = DSPDLINOFF;
u32 dspsize_reg_d = DSPDSIZE;
u32 dspsurf_reg_d = DSPDSURF;
/* values */
u32 pipeconf_val = 0;
u32 pipesrc_val = 0;
u32 vtot_val = 0;
u32 vblank_val = 0;
u32 vsync_val = 0;
u32 dspcntr_val = 0;
u32 dspstride_val = 0;
u32 dsplinoff_val = 0;
u32 dspsize_val = 0;
u32 dspsurf_val = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x\n", pipe);
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
pipesrc_val = REG_READ(pipesrc_reg);
vtot_val = REG_READ(vtot_reg);
vblank_val = REG_READ(vblank_reg);
vsync_val = REG_READ(vsync_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspstride_val = REG_READ(dspstride_reg);
dsplinoff_val = REG_READ(dsplinoff_reg);
dspsize_val = REG_READ(dspsize_reg);
dspsurf_val = REG_READ(dspsurf_reg);
/* Disable pipe and port. */
mrfld_disable_crtc(dev, pipe, true);
/* Set up the pll, two times 2D clock. */
/* mrfld_setup_pll (dev, pipe, adjusted_mode->clock); */
/* Set up from either full Top-and-Bottom or side-by-side to
* full side-by-side display 3D format.
*/
/* set up pipe related registers */
REG_WRITE(pipesrc_reg, (((pipesrc_val & 0x0000FFFF) + 1) * 2 - 1) |
(pipesrc_val & 0xFFFF0000));
REG_WRITE(vtot_reg, (vtot_val + 0x00010001) * 2 - 0x00010001);
REG_WRITE(vblank_reg, (vblank_val + 0x00010001) * 2 - 0x00010001);
REG_WRITE(vsync_reg, (vsync_val + 0x00010001) * 2 - 0x00010001);
/* set up plane related registers */
REG_WRITE(dspsize_reg_d, dspsize_val);
/* need to figure out the stride, offset and start. */
REG_WRITE(dspstride_reg, dspstride_val * 2);
REG_WRITE(dspstride_reg_d, dspstride_val * 2);
REG_WRITE(dsplinoff_reg, dsplinoff_val);
REG_WRITE(dsplinoff_reg_d, dsplinoff_val + dspstride_val);
REG_WRITE(dspsurf_reg, dspsurf_val);
REG_WRITE(dspsurf_reg_d, dspsurf_val);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
/* send 3D info frame. */
/*enable the plane */
REG_WRITE(dspcntr_reg_d, dspcntr_val);
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
dspcntr_val |= S3D_SPRITE_ORDER_A_FIRST | S3D_SPRITE_INTERLEAVING_LINE;
REG_WRITE(dspcntr_reg, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
/* set up Vendor Specific InfoFrame for 3D format. */
if (pipe == 1)
mrfld_set_up_s3d_InfoFrame(dev, S3D_LINE_ALTERNATIVE);
return 0;
}
/**
* Perform display 3D mode set from full side-by-side to side-by-side 3D display.
*
*/
static int mrfld_s3d_side_by_side(struct drm_device *dev, int pipe)
{
DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
/* regester */
u32 pipeconf_reg = PIPEBCONF;
u32 pipesrc_reg = PIPEBSRC;
u32 htot_reg = HTOTAL_B;
u32 hblank_reg = HBLANK_B;
u32 hsync_reg = HSYNC_B;
u32 dspcntr_reg = DSPBCNTR;
u32 dspstride_reg = DSPBSTRIDE;
u32 dsplinoff_reg = DSPBLINOFF;
u32 dspsize_reg = DSPBSIZE;
u32 dspsurf_reg = DSPBSURF;
u32 dspcntr_reg_d = DSPDCNTR;
u32 dspstride_reg_d = DSPDSTRIDE;
u32 dsplinoff_reg_d = DSPDLINOFF;
u32 dspsize_reg_d = DSPDSIZE;
u32 dspsurf_reg_d = DSPDSURF;
/* values */
u32 pipeconf_val = 0;
u32 pipesrc_val = 0;
u32 htot_val = 0;
u32 hblank_val = 0;
u32 hsync_val = 0;
u32 dspcntr_val = 0;
u32 dspstride_val = 0;
u32 dsplinoff_val = 0;
u32 dspsize_val = 0;
u32 dspsurf_val = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x\n", pipe);
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
pipesrc_val = REG_READ(pipesrc_reg);
htot_val = REG_READ(htot_reg);
hblank_val = REG_READ(hblank_reg);
hsync_val = REG_READ(hsync_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspstride_val = REG_READ(dspstride_reg);
dsplinoff_val = REG_READ(dsplinoff_reg);
dspsize_val = REG_READ(dspsize_reg);
dspsurf_val = REG_READ(dspsurf_reg);
/* Disable pipe and port. */
mrfld_disable_crtc(dev, pipe, true);
/* Set up the pll, two times 2D clock. */
/* mrfld_setup_pll (dev, pipe, adjusted_mode->clock); */
/* Set up from full side-by-side to full side-by-side display 3D format. */
/* set up pipe related registers */
REG_WRITE(pipesrc_reg, (pipesrc_val & 0x0000FFFF) |
(((pipesrc_val & 0xFFFF0000) + 0x00010000) * 2 - 0x00010000));
REG_WRITE(htot_reg, (htot_val + 0x00010001) * 2 - 0x00010001);
REG_WRITE(hblank_reg, (hblank_val + 0x00010001) * 2 - 0x00010001);
REG_WRITE(hsync_reg, (hsync_val + 0x00010001) * 2 - 0x00010001);
/* set up plane related registers */
REG_WRITE(dspsize_reg_d, dspsize_val);
/* need to figure out the stride, offset and start. */
REG_WRITE(dspstride_reg, dspstride_val * 2);
REG_WRITE(dspstride_reg_d, dspstride_val * 2);
REG_WRITE(dsplinoff_reg, dsplinoff_val);
REG_WRITE(dsplinoff_reg_d, dsplinoff_val + dspstride_val);
REG_WRITE(dspsurf_reg, dspsurf_val);
REG_WRITE(dspsurf_reg_d, dspsurf_val);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
/* send 3D info frame. */
/*enable the plane */
REG_WRITE(dspcntr_reg_d, dspcntr_val);
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
dspcntr_val |= S3D_SPRITE_ORDER_A_FIRST | S3D_SPRITE_INTERLEAVING_LINE;
REG_WRITE(dspcntr_reg, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
/* set up Vendor Specific InfoFrame for 3D format. */
if (pipe == 1)
mrfld_set_up_s3d_InfoFrame(dev, S3D_SIDE_BY_SIDE_FULL);
return 0;
}
/**
* Perform display 3D mode set from half side-by-side to half side-by-side 3D display.
*
*/
static int mrfld_s3d_half_side_by_side(struct drm_device *dev, int pipe)
{
DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
/* regester */
u32 dspsurf_reg = DSPASURF;
/* values */
u32 dspsurf_val = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x\n", pipe);
dspsurf_val = REG_READ(dspsurf_reg);
/* need to figure out the start. */
REG_WRITE(dspsurf_reg, dspsurf_val);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
/* set up Vendor Specific InfoFrame for 3D format. */
if (pipe == 1)
mrfld_set_up_s3d_InfoFrame(dev, S3D_SIDE_BY_SIDE_HALF);
return 0;
}
/**
* Perform display 3D mode set from full Top_Bottom to frame packing 3D display.
*
*/
static int mrfld_s3d_frame_packing(struct drm_device *dev, int pipe)
{
DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
/* regester */
u32 pipeconf_reg = PIPEBCONF;
u32 pipesrc_reg = PIPEBSRC;
u32 vtot_reg = VTOTAL_B;
u32 vblank_reg = VBLANK_B;
u32 vsync_reg = VSYNC_B;
u32 dspcntr_reg = DSPBCNTR;
u32 dspstride_reg = DSPBSTRIDE;
u32 dsplinoff_reg = DSPBLINOFF;
u32 dspsize_reg = DSPBSIZE;
u32 dspsurf_reg = DSPBSURF;
/* values */
u32 pipeconf_val = 0;
u32 pipesrc_val = 0;
u32 vtot_val = 0;
u32 vblank_val = 0;
u32 vsync_val = 0;
u32 dspcntr_val = 0;
u32 dspstride_val = 0;
u32 dsplinoff_val = 0;
u32 dspsize_val = 0;
u32 dspsurf_val = 0;
u32 temp = 0;
u32 temp1 = 0;
u32 temp2 = 0;
u32 temp3 = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
if (pipe != 1) {
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
pipesrc_val = REG_READ(pipesrc_reg);
vtot_val = REG_READ(vtot_reg);
vblank_val = REG_READ(vblank_reg);
vsync_val = REG_READ(vsync_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspstride_val = REG_READ(dspstride_reg);
dsplinoff_val = REG_READ(dsplinoff_reg);
dspsize_val = REG_READ(dspsize_reg);
dspsurf_val = REG_READ(dspsurf_reg);
/* Disable pipe and port. */
mrfld_disable_crtc(dev, pipe, true);
/* Set up the pll, two times 2D clock. */
/* mrfld_setup_pll (dev, pipe, adjusted_mode->clock); */
/* Set up frame packing display 3D format. */
/* set up pipe related registers */
REG_WRITE(pipesrc_reg, (((pipesrc_val & 0x0000FFFF) + 1) * 2 - 1) |
(pipesrc_val & 0xFFFF0000));
/* Get the 3D Vactive. */
temp = ((vtot_val & 0xFFFF0000) >> 16) - (vtot_val & 0x0000FFFF);
temp += ((vtot_val & 0x0000FFFF) + 1) * 2 - 1;
/* Get the 3D Vtotal. */
temp1 = ((vtot_val & 0xFFFF0000) + 0x00010000) * 2 - 0x00010000;
REG_WRITE(vtot_reg, temp1 | temp);
/* Get the 3D Vblank. */
temp2 = (vblank_val & 0x0000FFFF) - (vtot_val & 0x0000FFFF);
temp3 = (vtot_val & 0xFFFF0000) - (vblank_val & 0xFFFF0000);
REG_WRITE(vblank_reg, (temp1 - temp3) | (temp + temp2));
/* Get the 3D Vsync */
temp2 = (vsync_val & 0x0000FFFF) - (vtot_val & 0x0000FFFF);
temp3 = (vtot_val & 0xFFFF0000) - (vsync_val & 0xFFFF0000);
REG_WRITE(vblank_reg, (temp1 - temp3) | (temp + temp2));
/* set up plane related registers */
REG_WRITE(dspsize_reg, (((dspsize_val & 0xFFFF0000) + 0x00010000) * 2 -
0x00010000) | (dspsize_val & 0x0000FFFF));
/* need to figure out the offset and start. */
REG_WRITE(dsplinoff_reg, dsplinoff_val);
REG_WRITE(dspsurf_reg, dspsurf_val);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
/* send 3D info frame. */
/*enable the plane */
REG_WRITE(dspcntr_reg, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
/* set up Vendor Specific InfoFrame for 3D format. */
if (pipe == 1)
mrfld_set_up_s3d_InfoFrame(dev, S3D_FRAME_PACKING);
return 0;
}
/**
* Perform display 3D mode set from half Top_Bottom to line interleaving 3D display.
*
*/
static int mrfld_s3d_half_top_bottom_to_line_interleave(struct drm_device *dev,
int pipe)
{
DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
struct mdfld_dsi_config *dsi_config = dev_priv->dsi_configs[0];
/* regester */
u32 pipeconf_reg = PIPEACONF;
u32 dspcntr_reg = DSPACNTR;
u32 dspstride_reg = DSPASTRIDE;
u32 dsplinoff_reg = DSPALINOFF;
u32 dspsize_reg = DSPASIZE;
u32 dspsurf_reg = DSPASURF;
u32 mipi_reg = MIPI;
u32 dspcntr_reg_d = DSPDCNTR;
u32 dspstride_reg_d = DSPDSTRIDE;
u32 dsplinoff_reg_d = DSPDLINOFF;
u32 dspsize_reg_d = DSPDSIZE;
u32 dspsurf_reg_d = DSPDSURF;
/* values */
u32 pipeconf_val = 0;
u32 dspcntr_val = 0;
u32 dspstride_val = 0;
u32 dsplinoff_val = 0;
u32 dspsize_val = 0;
u32 dspsurf_val = 0;
u32 mipi_val = 0;
PSB_DEBUG_ENTRY("pipe = 0x%x \n", pipe);
switch (pipe) {
case 0:
break;
case 2:
dsi_config = dev_priv->dsi_configs[1];
pipeconf_reg = PIPECCONF;
dspcntr_reg = DSPCCNTR;
dspstride_reg = DSPCSTRIDE;
dsplinoff_reg = DSPCLINOFF;
dspsize_reg = DSPCSIZE;
dspsurf_reg = DSPCSURF;
mipi_reg = MIPI_C;
break;
default:
DRM_ERROR("Illegal Pipe Number. \n");
return 0;
}
/* Save the related DC registers. */
pipeconf_val = REG_READ(pipeconf_reg);
dspcntr_val = REG_READ(dspcntr_reg);
dspstride_val = REG_READ(dspstride_reg);
dsplinoff_val = REG_READ(dsplinoff_reg);
dspsize_val = REG_READ(dspsize_reg);
dspsurf_val = REG_READ(dspsurf_reg);
mipi_val = REG_READ(mipi_reg);
/* Disable pipe and port, don't disable the PLL. */
/* FIXME modify the following function with option to disable PLL or
* not.
* */
mrfld_disable_crtc(dev, pipe, true);
/* Set up line interleaving display 3D format. */
REG_WRITE(dspsize_reg, (((dspsize_val & 0xFFFF0000) + 0x00010000) / 2 -
0x00010000) | (dspsize_val & 0x0000FFFF));
REG_WRITE(dspsize_reg_d,
(((dspsize_val & 0xFFFF0000) + 0x00010000) / 2 -
0x00010000) | (dspsize_val & 0x0000FFFF));
REG_WRITE(dspstride_reg_d, dspstride_val);
/* need to figure out the offset and start. */
REG_WRITE(dsplinoff_reg, dsplinoff_val);
REG_WRITE(dsplinoff_reg_d, dsplinoff_val
+ (((dspsize_val >> 16) + 1) / 2) * dspstride_val);
REG_WRITE(dspsurf_reg, dspsurf_val);
REG_WRITE(dspsurf_reg_d, dspsurf_val);
/* Try to attach/de-attach Plane B to an existing swap chain,
* especially with another frame buffer inserted into GTT. */
/* eError = MRSTLFBChangeSwapChainProperty(&Start, pipe); */
/*set up mipi port related registers */
REG_WRITE(mipi_reg, mipi_val);
/*setup MIPI adapter + MIPI IP registers */
/* mdfld_dsi_controller_init(dsi_config, pipe); */
mdelay(20); /* msleep(20); */
/* re-init the panel */
dsi_config->drv_ic_inited = 0;
/* mdfld_dsi_tmd_drv_ic_init(dsi_config, pipe); */
/*enable the plane */
REG_WRITE(dspcntr_reg_d, dspcntr_val);
dspcntr_val &= ~(S3D_SPRITE_ORDER_BITS | S3D_SPRITE_INTERLEAVING_BITS);
dspcntr_val |= S3D_SPRITE_ORDER_A_FIRST | S3D_SPRITE_INTERLEAVING_LINE;
REG_WRITE(dspcntr_reg, dspcntr_val);
mdelay(20); /* msleep(20); */
/* psb_intel_wait_for_vblank(dev); */
/*enable the pipe */
REG_WRITE(pipeconf_reg, pipeconf_val);
/* set up Vendor Specific InfoFrame for 3D format. */
if (pipe == 1)
mrfld_set_up_s3d_InfoFrame(dev, S3D_LINE_ALTERNATIVE);
return 0;
}
/* MDFLD_PLATFORM start */
void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe)
{
int count, temp;
u32 pipeconf_reg = PIPEACONF;
switch (pipe) {
case 0:
break;
case 1:
pipeconf_reg = PIPEBCONF;
break;
case 2:
pipeconf_reg = PIPECCONF;
break;
default:
DRM_ERROR("Illegal Pipe Number. \n");
return;
}
/* Wait for for the pipe disable to take effect. */
for (count = 0; count < COUNT_MAX; count++) {
temp = REG_READ(pipeconf_reg);
if (!(temp & PIPEACONF_PIPE_STATE))
break;
udelay(20);
}
PSB_DEBUG_ENTRY("cout = %d. \n", count);
}
void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe)
{
int count, temp;
u32 pipeconf_reg = PIPEACONF;
switch (pipe) {
case 0:
break;
case 1:
pipeconf_reg = PIPEBCONF;
break;
case 2:
pipeconf_reg = PIPECCONF;
break;
default:
DRM_ERROR("Illegal Pipe Number. \n");
return;
}
/* Wait for for the pipe enable to take effect. */
for (count = 0; count < COUNT_MAX; count++) {
temp = REG_READ(pipeconf_reg);
if ((temp & PIPEACONF_PIPE_STATE))
break;
udelay(20);
}
PSB_DEBUG_ENTRY("cout = %d. \n", count);
}
static int mdfld_intel_crtc_cursor_set(struct drm_crtc *crtc,
struct drm_file *file_priv,
uint32_t handle,
uint32_t width, uint32_t height)
{
struct drm_device *dev = crtc->dev;
struct drm_psb_private *dev_priv =
(struct drm_psb_private *)dev->dev_private;
struct psb_gtt *pg = dev_priv->pg;
struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
struct psb_intel_mode_device *mode_dev = psb_intel_crtc->mode_dev;
int pipe = psb_intel_crtc->pipe;
uint32_t control = CURACNTR;
uint32_t base = CURABASE;
uint32_t temp;
size_t addr = 0;
uint32_t page_offset;
size_t size;
void *bo;
int ret;
DRM_DEBUG("\n");
#ifdef CONFIG_SUPPORT_MIPI
switch (pipe) {
case 0:
break;
case 1:
control = CURBCNTR;
base = CURBBASE;
break;
case 2:
control = CURCCNTR;
base = CURCBASE;
break;
default:
DRM_ERROR("Illegal Pipe Number. \n");
return -EINVAL;
}
/* Can't enalbe HW cursor on plane B/C. */
if (pipe != 0)
return 0;
/* if we want to turn of the cursor ignore width and height */
if (!handle) {
DRM_DEBUG("cursor off\n");
/* turn off the cursor */
temp = 0;
temp |= CURSOR_MODE_DISABLE;
REG_WRITE(control, temp);
REG_WRITE(base, 0);
/* unpin the old bo */
if (psb_intel_crtc->cursor_bo) {
mode_dev->bo_unpin_for_scanout(dev,
psb_intel_crtc->
cursor_bo);
psb_intel_crtc->cursor_bo = NULL;
}
return 0;
}
/* Currently we only support 64x64 cursors */
if (width != 64 || height != 64) {
DRM_ERROR("we currently only support 64x64 cursors\n");
return -EINVAL;
}
bo = mode_dev->bo_from_handle(dev, file_priv, handle);
if (!bo)
return -ENOENT;
ret = mode_dev->bo_pin_for_scanout(dev, bo);
if (ret)
return ret;
size = mode_dev->bo_size(dev, bo);
if (size < width * height * 4) {
DRM_ERROR("buffer is to small\n");
return -ENOMEM;
}
/*insert this bo into gtt */
// DRM_INFO("%s: map meminfo for hw cursor. handle %x, pipe = %d \n", __FUNCTION__, handle, pipe);
ret = psb_gtt_map_meminfo(dev, (IMG_HANDLE) handle, 0, &page_offset);
if (ret) {
DRM_ERROR("Can not map meminfo to GTT. handle 0x%x\n", handle);
return ret;
}
addr = page_offset << PAGE_SHIFT;
psb_intel_crtc->cursor_addr = addr;
temp = 0;
/* set the pipe for the cursor */
temp |= (pipe << 28);
temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
REG_WRITE(control, temp);
REG_WRITE(base, addr);
/* unpin the old bo */
if (psb_intel_crtc->cursor_bo && psb_intel_crtc->cursor_bo != bo) {
mode_dev->bo_unpin_for_scanout(dev, psb_intel_crtc->cursor_bo);
psb_intel_crtc->cursor_bo = bo;
}
#endif
return 0;
}
static struct drm_device globle_dev;
void mdfld__intel_plane_set_alpha(int enable)
{
struct drm_device *dev = &globle_dev;
int dspcntr_reg = DSPACNTR;
u32 dspcntr;
dspcntr = REG_READ(dspcntr_reg);
if (enable) {
dspcntr &= ~DISPPLANE_32BPP_NO_ALPHA;
dspcntr |= DISPPLANE_32BPP;
} else {
dspcntr &= ~DISPPLANE_32BPP;
dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
}
REG_WRITE(dspcntr_reg, dspcntr);
}
/**
* Disable the pipe, plane and pll.
*
*/
void mdfld_disable_crtc(struct drm_device *dev, int pipe)
{
int dpll_reg = MRST_DPLL_A;
int dspcntr_reg = DSPACNTR;
int dspbase_reg = MRST_DSPABASE;
int pipeconf_reg = PIPEACONF;
u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
u32 temp;
PSB_DEBUG_ENTRY("pipe = %d\n", pipe);
switch (pipe) {
#ifdef CONFIG_SUPPORT_MIPI
case 0:
break;
#endif
case 1:
dpll_reg = MDFLD_DPLL_B;
dspcntr_reg = DSPBCNTR;
dspbase_reg = DSPBSURF;
pipeconf_reg = PIPEBCONF;
break;
#ifdef CONFIG_SUPPORT_MIPI
case 2:
dpll_reg = MRST_DPLL_A;
dspcntr_reg = DSPCCNTR;
dspbase_reg = MDFLD_DSPCBASE;
pipeconf_reg = PIPECCONF;
gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
break;
#endif
default:
DRM_ERROR("Illegal Pipe Number.\n");
return;
}
#ifdef CONFIG_SUPPORT_MIPI
if (pipe != 1)
mdfld_dsi_gen_fifo_ready(dev, gen_fifo_stat_reg,
HS_CTRL_FIFO_EMPTY |
HS_DATA_FIFO_EMPTY);
#endif
/* Disable display plane */
temp = REG_READ(dspcntr_reg);
if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
REG_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
/* Flush the plane changes */
REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
REG_READ(dspbase_reg);
}
/* Next, disable display pipes */
temp = REG_READ(pipeconf_reg);
if ((temp & PIPEACONF_ENABLE) != 0) {
temp &= ~PIPEACONF_ENABLE;
temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
REG_WRITE(pipeconf_reg, temp);
REG_READ(pipeconf_reg);
/* Wait for for the pipe disable to take effect. */
mdfldWaitForPipeDisable(dev, pipe);
}
temp = REG_READ(dpll_reg);
if (temp & DPLL_VCO_ENABLE) {
if (((pipe != 1)
&& !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) &
PIPEACONF_ENABLE))
|| (pipe == 1)) {
temp &= ~(DPLL_VCO_ENABLE);
REG_WRITE(dpll_reg, temp);
REG_READ(dpll_reg);
/* Wait for the clocks to turn off. */
/* FIXME_MDFLD PO may need more delay */
udelay(500);
if (!(temp & MDFLD_PWR_GATE_EN)) {
/* gating power of DPLL */
REG_WRITE(dpll_reg, temp | MDFLD_PWR_GATE_EN);
/* FIXME_MDFLD PO - change 500 to 1 after PO */
udelay(5000);
}
}
}
}
/* MDFLD_PLATFORM end */
#endif