/*
* Copyright © 2006-2007 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*
* Authors:
* Eric Anholt <eric@anholt.net>
*/
#include <linux/i2c.h>
#include <linux/pm_runtime.h>
#include <drm/drmP.h>
#include "psb_intel_reg.h"
#include "psb_intel_display.h"
#include "framebuffer.h"
#include "mdfld_output.h"
#include "mdfld_dsi_output.h"
/* Hardcoded currently */
static int ksel = KSEL_CRYSTAL_19;
struct psb_intel_range_t {
int min, max;
};
struct mrst_limit_t {
struct psb_intel_range_t dot, m, p1;
};
struct mrst_clock_t {
/* derived values */
int dot;
int m;
int p1;
};
#define COUNT_MAX 0x10000000
void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe)
{
struct drm_psb_private *dev_priv = dev->dev_private;
const struct psb_offset *map = &dev_priv->regmap[pipe];
int count, temp;
switch (pipe) {
case 0:
case 1:
case 2:
break;
default:
DRM_ERROR("Illegal Pipe Number.\n");
return;
}
/* FIXME JLIU7_PO */
psb_intel_wait_for_vblank(dev);
return;
/* Wait for for the pipe disable to take effect. */
for (count = 0; count < COUNT_MAX; count++) {
temp = REG_READ(map->conf);
if ((temp & PIPEACONF_PIPE_STATE) == 0)
break;
}
}
void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe)
{
struct drm_psb_private *dev_priv = dev->dev_private;
const struct psb_offset *map = &dev_priv->regmap[pipe];
int count, temp;
switch (pipe) {
case 0:
case 1:
case 2:
break;
default:
DRM_ERROR("Illegal Pipe Number.\n");
return;
}
/* FIXME JLIU7_PO */
psb_intel_wait_for_vblank(dev);
return;
/* Wait for for the pipe enable to take effect. */
for (count = 0; count < COUNT_MAX; count++) {
temp = REG_READ(map->conf);
if ((temp & PIPEACONF_PIPE_STATE) == 1)
break;
}
}
static void psb_intel_crtc_prepare(struct drm_crtc *crtc)
{
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
}
static void psb_intel_crtc_commit(struct drm_crtc *crtc)
{
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
}
static bool psb_intel_crtc_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
return true;
}
/**
* Return the pipe currently connected to the panel fitter,
* or -1 if the panel fitter is not present or not in use
*/
static int psb_intel_panel_fitter_pipe(struct drm_device *dev)
{
u32 pfit_control;
pfit_control = REG_READ(PFIT_CONTROL);
/* See if the panel fitter is in use */
if ((pfit_control & PFIT_ENABLE) == 0)
return -1;
/* 965 can place panel fitter on either pipe */
return (pfit_control >> 29) & 0x3;
}
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;
}