aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/emgd/emgd/display/mode/plb/clocks_plb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/emgd/emgd/display/mode/plb/clocks_plb.c')
-rw-r--r--drivers/gpu/drm/emgd/emgd/display/mode/plb/clocks_plb.c512
1 files changed, 0 insertions, 512 deletions
diff --git a/drivers/gpu/drm/emgd/emgd/display/mode/plb/clocks_plb.c b/drivers/gpu/drm/emgd/emgd/display/mode/plb/clocks_plb.c
deleted file mode 100644
index eaa16d53b43e..000000000000
--- a/drivers/gpu/drm/emgd/emgd/display/mode/plb/clocks_plb.c
+++ /dev/null
@@ -1,512 +0,0 @@
-/* -*- pse-c -*-
- *-----------------------------------------------------------------------------
- * Filename: clocks_plb.c
- * $Revision: 1.5 $
- *-----------------------------------------------------------------------------
- * Copyright © 2002-2010, 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.
- *
- *-----------------------------------------------------------------------------
- * Description:
- *
- *-----------------------------------------------------------------------------
- */
-
-#define MODULE_NAME hal.mode
-
-#include <io.h>
-
-#include <igd_mode.h>
-#include <igd_init.h>
-
-#include <context.h>
-#include <intelpci.h>
-#include <dsp.h>
-#include <utils.h>
-#include <mode.h>
-#include <pi.h>
-#include <sched.h>
-
-#include <plb/regs.h>
-
-/*!
- * @addtogroup display_group
- * @{
- */
-
-/*===========================================================================
-; File Global Data
-;--------------------------------------------------------------------------*/
-typedef struct _fixed_clock {
- unsigned long dclk;
- unsigned long n;
- unsigned long m1;
- unsigned long m2;
- unsigned long p;
-}fixed_clock_t;
-
-static fixed_clock_t fixed_clock_table[] = {
- /* Clock N M1 M2 Post Div */
- { 43163, 0x03, 0x12, 0x06, 0x84}, /* 43.163 GTF for 640x480 @ 100Hz */
- { 81624, 0x03, 0x18, 0x04, 0x82}, /* 81.624MHz */
- {0xffffffff, 0x00, 0x00, 0x00, 0x00}
-};
-
-/*!
- * This function translates from the calculated M value to the M1, M2
- * register values.
- *
- * @param m
- * @param *m1
- * @param *m2
- *
- * @return 0 on success
- * @return 1 on failure
- */
-static int calculate_m1_m2(unsigned long m,
- unsigned long *m1,
- unsigned long *m2)
-{
- unsigned long current_m1, current_m2;
-
- EMGD_DEBUG("Enter calculate_m1_m2 %d", 1);
-
- /* ori was in steps of 2*/
- for(current_m1 = (10+2); current_m1 <= (20+2); current_m1 += 1) {
- for(current_m2 = (5+2); current_m2 <= (9+2); current_m2++) {
- if((current_m1 * 5 + current_m2) == m) {
- *m1 = current_m1 - 2;
- *m2 = current_m2 - 2;
- return 0;
- }
-
- }
- }
-
- EMGD_DEBUG("M1, M2 not found for M == %ld", m);
- return 1;
-}
-
-#define MAX_M 120 //216
-#define MIN_M 70 //96
-
-#define MAX_N 8 //16
-#define MIN_N 3
-
-#define MAX_P 80 //126
-#define MIN_P 5 //2
-
-#define LVDS_MAX_P 98
-#define LVDS_MIN_P 7
-
-#define FIX_P2_LO 5 //126
-#define FIX_P2_HI 10 //2
-
-#define MAX_P1 8 //126
-#define MIN_P1 1 //2
-
-#define REF_FREQ 96000 //48000
-#define MAX_VCO 2800000 //1400000
-#define MAX_FP 200000
-/* For LVDS port */
-#define LVDS_FIX_P2_LO 7
-#define LVDS_FIX_P2_HI 14
-
-/*!
- *
- * @param dclk
- * @param ref_freq
- * @param m1
- * @param m2
- * @param n
- * @param p
- * @param min_vco
- * @param target_error
- * @param port_type
- * @param dual_channel
- *
- * @return 0 on success
- * @return 1 on failure
- */
-static int calculate_clock(unsigned long dclk,
- unsigned long ref_freq,
- unsigned long *m1,
- unsigned long *m2,
- unsigned long *n,
- unsigned long *p,
- unsigned long min_vco,
- unsigned long target_error,
- unsigned long port_type,
- unsigned long dual_channel)
-
-{
- unsigned long p1;
- unsigned long p2;
- /* Parameters */
- unsigned long freqmult_p2;
-
- /* Intermidiate variables */
- unsigned long pdiv;
- unsigned long target_vco, actual_freq, actual_vco;
- long freq_error, min_error;
-
- unsigned long current_m, current_n, current_p1;
- unsigned long best_m = 0;
- unsigned long best_n = 0;
- unsigned long best_p1 = 0;
-
-
- EMGD_DEBUG("Enter calculate_clock");
-
- min_error = 100000;
-
- if (dclk > MAX_FP) {
- freqmult_p2 = FIX_P2_LO;
- } else {
- freqmult_p2 = FIX_P2_HI;
- }
-
- /* For LVDS port */
- if(port_type==IGD_PORT_LVDS){
- /* Test if we are dual channel */
- if(dual_channel){
- freqmult_p2=LVDS_FIX_P2_LO;
- } else{
- freqmult_p2=LVDS_FIX_P2_HI;
- }
-
- }
-
- for(current_m = MIN_M; current_m <= MAX_M; current_m++) {
- for(current_n = MIN_N; current_n < MAX_N; current_n++) {
- for(current_p1 = MIN_P1; current_p1 <= MAX_P1; current_p1++) {
-
- pdiv = freqmult_p2 * current_p1;
- target_vco = dclk * pdiv;
-
- if ((target_vco <= MAX_VCO) && (target_vco >= min_vco)) {
- actual_freq = (ref_freq * current_m) /
- (current_n * pdiv);
- actual_vco = actual_freq * pdiv;
- freq_error = 10000 - (dclk * 10000 / actual_freq);
-
- if (freq_error < 0) {
- freq_error = -freq_error;
- }
- if (freq_error < min_error) {
- best_n = current_n;
- best_m = current_m;
- best_p1 = current_p1;
- min_error = freq_error;
- }
- if (min_error == 0) {
- break;
- }
- }
- }
- if (min_error == 0) {
- break;
- }
- }
- if (min_error == 0) {
- break;
- }
- }
- /*
- * No clock found that meets error requirement
- */
- if (min_error > (long)target_error) {
- return 1;
- }
-
-
- /* Translate M,N,P to m1,m2,n,p register values */
- *n = best_n - 2;
- if(calculate_m1_m2(best_m, m1, m2)) {
- /* No M1, M2 match for M */
- return 1;
- }
-
- p1 = (1 << (best_p1-1));
- if((freqmult_p2-5)) {
- p2 = 0x0;
- }
- else {
- p2 = 0x1;
- }
- /* Set p2 for LVDS */
- if(port_type==IGD_PORT_LVDS){
- if(dual_channel){
- p2=0x1;
- }else{
- p2=0x0;
- }
-
- }
- *p = ( p1 | (p2<<8) );
-
- return 0;
-}
-
-#define MIN_VCO_PASS1 2000000 //1000000
-#define MIN_VCO_PASS2 1400000 //930000
-
-/*!
- *
- * @param dclk
- * @param ref_freq
- * @param m1
- * @param m2
- * @param n
- * @param p
- * @param target_error
- * @param port_type
- * @param dual_channel
- *
- * @return 0 on success
- * @return 1 on failure
- */
-static int get_clock(unsigned long dclk,
- unsigned long ref_freq,
- unsigned long *m1,
- unsigned long *m2,
- unsigned long *n,
- unsigned long *p,
- unsigned long target_error,
- unsigned long port_type,
- unsigned long dual_channel)
-{
- fixed_clock_t *fixed = fixed_clock_table;
-
- EMGD_DEBUG("Enter get_clock");
-
- /*
- * First check for a fixed clock from the table. These are ones that
- * can't be calculated correctly.
- */
- while(fixed->dclk != 0xffffffff) {
- if(fixed->dclk == dclk) {
- EMGD_DEBUG("Using Fixed Clock From table for clock %ld", dclk);
- *m1 = fixed->m1;
- *m2 = fixed->m2;
- *n = fixed->n;
- *p = fixed->p;
- return 0;
- }
- fixed++;
- }
-
-
- /*
- * No fixed clock found so calculate one.
- */
- EMGD_DEBUG("Calculating dynamic clock for clock %ld", dclk);
-
- /*
- * First pass try to find a clock with min_vco at 1000000.
- * If a clock doesn't come out then try 930000.
- */
- if(calculate_clock(dclk, ref_freq, m1, m2, n, p, MIN_VCO_PASS1,
- target_error,port_type,dual_channel)) {
- if(calculate_clock(dclk, ref_freq, m1, m2, n, p, MIN_VCO_PASS2,
- target_error,port_type,dual_channel)) {
- /* No usable clock */
- EMGD_ERROR("Could not calculate clock %ld, returning default.",
- dclk);
- *m1 = 0x14;
- *m2 = 0xc;
- *n = 0x3;
- *p = 0x82;
- return 1;
- }
- }
-
- return 0;
-}
-
-#define TARGET_ERROR 46
-
-/*!
- *
- * @param display
- * @param clock
- * @param dclk
- *
- * @return 0 on success
- * @return 1 on failure
- */
-int program_clock_plb(igd_display_context_t *display,
- igd_clock_t *clock,
- unsigned long dclk)
-{
- unsigned long m1, m2, n, p;
- unsigned long control;
- unsigned long ref_freq;
- int ret;
- igd_display_port_t *port;
- unsigned long port_mult, vga_mult;
- unsigned long dual_channel = 0;
- unsigned long index;
-
- EMGD_DEBUG("Enter program_clock");
-
- port=PORT_OWNER(display);
-
- if (dclk > 100000) { /* 100-200 MHz */
-
- port_mult = 1;
- }
- else if (dclk > 50000) { /* 50-100 Mhz */
-
- port_mult = 2;
- }
- else { /* 25-50 Mhz */
-
- port_mult = 4;
- }
-
- /*
- * Clock Multiplier : sDVO ports on all plb chipsets
- */
- if (port->port_type == IGD_PORT_DIGITAL) {
-
- dclk *= port_mult;
- }
-
- vga_mult = READ_MMIO_REG(display, clock->dpll_control) & 0x3;
-
- /* For Int-LVDS need to find out if its dual channel and pass
- * that info into caluculating for p2. Apperently halving
- * of dot-clock is also required by Ch7017 when operating in
- * dual channel
- */
- if (port->port_type == IGD_PORT_LVDS) {
- /* Find PD_ATTR_ID_2_CHANNEL_PANEL attr value*/
- pi_pd_find_attr_and_value(PORT_OWNER(display),
- PD_ATTR_ID_2_CHANNEL_PANEL,
- 0/*no PD_FLAG for 2_channel*/,
- NULL,
- &dual_channel);
- }
-
- /* For external clock sources always use ref_clock == dclk */
- if(port->pd_flags & PD_FLAG_CLK_SOURCE) {
- ref_freq = dclk;
- } else {
- ref_freq = 96000;
- }
- /* LVDS reference clock can be 96 or 100 MHz. However there
- * are no mention in the specification to specify which register
- * to select/set this.
- */
-
- /* When the clock source is provided externally by the port driver,
- * the allowed error range is 0. */
- if(port->pd_flags & PD_FLAG_CLK_SOURCE) {
- ret = get_clock(dclk, ref_freq, &m1, &m2, &n, &p, 0
- ,port->port_type,dual_channel);
- } else {
- ret = get_clock(dclk, ref_freq, &m1, &m2, &n, &p, TARGET_ERROR
- ,port->port_type,dual_channel);
- }
-
- if(ret) {
- EMGD_ERROR("Clock %ld could not be programmed", dclk);
- return ret;
- }
-
- /* Disable DPLL, Write an 0x80 into P for saftey */
- control = 0x10000000 | (0x80<<clock->p_shift) | BIT26 | vga_mult;
- WRITE_MMIO_REG(display, clock->dpll_control, control);
-
- /* Program N, M1,and M2 */
- WRITE_MMIO_REG(display, clock->mnp, (n<<16) | (m1<<8) | m2);
-
- /* Enable DPLL, Disable VGAm Mode and sitck in new P values */
- if(port->port_type==IGD_PORT_LVDS){
- /* If LVDS set the appropriate bits for mode select */
- control = (BIT31 | BIT28 | BIT27 )
- | (p<<clock->p_shift) | vga_mult;
-
- if(port->attr_list) {
-
- for(index = 0; index < port->attr_list->num_attrs; index++) {
-
- /* Set spread spectrum and pulse phase */
- if(port->attr_list->attr[index].id == PD_ATTR_ID_SSC) {
-
- /*
- * Pulse Phase for Poulsbo only has valid values between
- * 3 and 9
- */
- if(port->attr_list->attr[index].value >= 3 &&
- port->attr_list->attr[index].value <= 9) {
-
- control |= BIT13 | BIT14;
- /*
- * Set the Pulse Phase to the clock phase specified by
- * the user
- */
- control |= (port->attr_list->attr[index].value<<9);
- }
- break;
- }
- }
- }
- } else{
- /* else DAC/SDVO */
- control = (BIT31 | BIT28 | BIT26) | (p<<clock->p_shift) | vga_mult;
- }
- /*
- * Poulsbo has high speed clock on always
- */
- control |= BIT30;
-
-
-
- /* Set the clock source correctly based on PD settings */
- if(port->pd_flags & PD_FLAG_CLK_SOURCE) {
- control |= port->clock_bits;
- } else {
- control |= port->clock_bits & ~0x00006000;
- }
-
- /* sDVO Multiplier bits[7:0] */
- if (port->port_type == IGD_PORT_DIGITAL) {
-
- if (port_mult == 2) {
-
- control |= (1 << 4);
-
- } else if (port_mult == 4) {
-
- control |= (3 << 4);
- }
- }
-
- WRITE_MMIO_REG(display, clock->dpll_control, control);
-
- /* We must wait for 150 us for the dpll clock to warm up */
- OS_SLEEP(150);
-
- return 0;
-}
-
-/*----------------------------------------------------------------------------
- * File Revision History
- * $Id: clocks_plb.c,v 1.5 2010/07/23 16:54:49 bpaauwe Exp $
- * $Source: /nfs/fm/proj/eia/cvsroot/koheo/linux/egd_drm/emgd/display/mode/plb/clocks_plb.c,v $
- *----------------------------------------------------------------------------
- */