/*
* Copyright © 2010 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>
* Jackie Li<yaodong.li@intel.com>
*/
#include "mdfld_dsi_dpi.h"
#include "mdfld_output.h"
#include "mdfld_dsi_pkg_sender.h"
#include "psb_drv.h"
#include "tc35876x-dsi-lvds.h"
static void mdfld_dsi_dpi_shut_down(struct mdfld_dsi_dpi_output *output,
int pipe);
static void mdfld_wait_for_HS_DATA_FIFO(struct drm_device *dev, u32 pipe)
{
u32 gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe);
int timeout = 0;
udelay(500);
/* This will time out after approximately 2+ seconds */
while ((timeout < 20000) &&
(REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_DATA_FULL)) {
udelay(100);
timeout++;
}
if (timeout == 20000)
DRM_INFO("MIPI: HS Data FIFO was never cleared!\n");
}
static void mdfld_wait_for_HS_CTRL_FIFO(struct drm_device *dev, u32 pipe)
{
u32 gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe);
int timeout = 0;
udelay(500);
/* This will time out after approximately 2+ seconds */
while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg)
& DSI_FIFO_GEN_HS_CTRL_FULL)) {
udelay(100);
timeout++;
}
if (timeout == 20000)
DRM_INFO("MIPI: HS CMD FIFO was never cleared!\n");
}
static void mdfld_wait_for_DPI_CTRL_FIFO(struct drm_device *dev, u32 pipe)
{
u32 gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe);
int timeout = 0;
udelay(500);
/* This will time out after approximately 2+ seconds */
while ((timeout < 20000) && ((REG_READ(gen_fifo_stat_reg) &
DPI_FIFO_EMPTY) != DPI_FIFO_EMPTY)) {
udelay(100);
timeout++;
}
if (timeout == 20000)
DRM_ERROR("MIPI: DPI FIFO was never cleared\n");
}
static void mdfld_wait_for_SPL_PKG_SENT(struct drm_device *dev, u32 pipe)
{
u32 intr_stat_reg = MIPI_INTR_STAT_REG(pipe);
int timeout = 0;
udelay(500);
/* This will time out after approximately 2+ seconds */
while ((timeout < 20000) && (!(REG_READ(intr_stat_reg)
& DSI_INTR_STATE_SPL_PKG_SENT))) {
udelay(100);
timeout++;
}
if (timeout == 20000)
DRM_ERROR("MIPI: SPL_PKT_SENT_INTERRUPT was not sent successfully!\n");
}
/* For TC35876X */
static void dsi_set_device_ready_state(struct drm_device *dev, int state,
int pipe)
{
REG_FLD_MOD(MIPI_DEVICE_READY_REG(pipe), !!state, 0, 0);
}
static void dsi_set_pipe_plane_enable_state(struct drm_device *dev,
int state, int pipe)
{
struct drm_psb_private *dev_priv = dev->dev_private;
u32 pipeconf_reg = PIPEACONF;
u32 dspcntr_reg = DSPACNTR;
u32 dspcntr = dev_priv->dspcntr[pipe];
u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;
if (pipe) {
pipeconf_reg = PIPECCONF;
dspcntr_reg = DSPCCNTR;
} else
mipi &= (~0x03);
if (state) {
/*Set up pipe */
REG_WRITE(pipeconf_reg, BIT(31));
if (REG_BIT_WAIT(pipeconf_reg, 1, 30))
dev_err(&dev->pdev->dev, "%s: Pipe enable timeout\n",
__func__);
/*Set up display plane */
REG_WRITE(dspcntr_reg, dspcntr);
} else {
u32 dspbase_reg = pipe ? MDFLD_DSPCBASE : MRST_DSPABASE;
/* Put DSI lanes to ULPS to disable pipe */
REG_FLD_MOD(MIPI_DEVICE_READY_REG(pipe), 2, 2, 1);
REG_READ(MIPI_DEVICE_READY_REG(pipe)); /* posted write? */
/* LP Hold */
REG_FLD_MOD(MIPI_PORT_CONTROL(pipe), 0, 16, 16);
REG_READ(MIPI_PORT_CONTROL(pipe)); /* posted write? */
/* Disable