These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / staging / sm750fb / ddk750_chip.c
index 7b28328..0331d34 100644 (file)
@@ -1,15 +1,9 @@
+#include <linux/sizes.h>
+
 #include "ddk750_help.h"
 #include "ddk750_reg.h"
 #include "ddk750_chip.h"
 #include "ddk750_power.h"
-typedef struct _pllcalparam {
-       unsigned char power;/* d : 0~ 6*/
-       unsigned char pod;
-       unsigned char od;
-       unsigned char value;/* value of  2 power d (2^d) */
-}
-pllcalparam;
-
 
 logical_chip_type_t getChipType(void)
 {
@@ -17,7 +11,7 @@ logical_chip_type_t getChipType(void)
        char physicalRev;
        logical_chip_type_t chip;
 
-       physicalID = devId750;//either 0x718 or 0x750
+       physicalID = devId750; /* either 0x718 or 0x750 */
        physicalRev = revId750;
 
        if (physicalID == 0x718)
@@ -33,82 +27,36 @@ logical_chip_type_t getChipType(void)
        return chip;
 }
 
-
-inline unsigned int twoToPowerOfx(unsigned long x)
+static unsigned int get_mxclk_freq(void)
 {
-       unsigned long i;
-       unsigned long result = 1;
-
-       for (i = 1; i <= x; i++)
-               result *= 2;
-       return result;
-}
-
-inline unsigned int calcPLL(pll_value_t *pPLL)
-{
-       return (pPLL->inputFreq * pPLL->M / pPLL->N / twoToPowerOfx(pPLL->OD) / twoToPowerOfx(pPLL->POD));
-}
-
-unsigned int getPllValue(clock_type_t clockType, pll_value_t *pPLL)
-{
-       unsigned int ulPllReg = 0;
-
-       pPLL->inputFreq = DEFAULT_INPUT_CLOCK;
-       pPLL->clockType = clockType;
+       unsigned int pll_reg;
+       unsigned int M, N, OD, POD;
 
-       switch (clockType) {
-       case MXCLK_PLL:
-               ulPllReg = PEEK32(MXCLK_PLL_CTRL);
-               break;
-       case PRIMARY_PLL:
-               ulPllReg = PEEK32(PANEL_PLL_CTRL);
-               break;
-       case SECONDARY_PLL:
-               ulPllReg = PEEK32(CRT_PLL_CTRL);
-               break;
-       case VGA0_PLL:
-               ulPllReg = PEEK32(VGA_PLL0_CTRL);
-               break;
-       case VGA1_PLL:
-               ulPllReg = PEEK32(VGA_PLL1_CTRL);
-               break;
-       }
-
-       pPLL->M = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, M);
-       pPLL->N = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, N);
-       pPLL->OD = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, OD);
-       pPLL->POD = FIELD_GET(ulPllReg, PANEL_PLL_CTRL, POD);
-
-       return calcPLL(pPLL);
-}
-
-
-unsigned int getChipClock(void)
-{
-       pll_value_t pll;
-#if 1
        if (getChipType() == SM750LE)
                return MHz(130);
-#endif
 
-       return getPllValue(MXCLK_PLL, &pll);
-}
+       pll_reg = PEEK32(MXCLK_PLL_CTRL);
+       M = FIELD_GET(pll_reg, PANEL_PLL_CTRL, M);
+       N = FIELD_GET(pll_reg, PANEL_PLL_CTRL, N);
+       OD = FIELD_GET(pll_reg, PANEL_PLL_CTRL, OD);
+       POD = FIELD_GET(pll_reg, PANEL_PLL_CTRL, POD);
 
+       return DEFAULT_INPUT_CLOCK * M / N / (1 << OD) / (1 << POD);
+}
 
 /*
  * This function set up the main chip clock.
  *
  * Input: Frequency to be set.
  */
-void setChipClock(unsigned int frequency)
+static void setChipClock(unsigned int frequency)
 {
        pll_value_t pll;
        unsigned int ulActualMxClk;
-#if 1
+
        /* Cheok_0509: For SM750LE, the chip clock is fixed. Nothing to set. */
        if (getChipType() == SM750LE)
                return;
-#endif
 
        if (frequency) {
                /*
@@ -129,16 +77,14 @@ void setChipClock(unsigned int frequency)
        }
 }
 
-
-
-void setMemoryClock(unsigned int frequency)
+static void setMemoryClock(unsigned int frequency)
 {
        unsigned int ulReg, divisor;
- #if 1
+
        /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */
        if (getChipType() == SM750LE)
                return;
-#endif
+
        if (frequency) {
                /* Set the frequency to the maximum frequency that the DDR Memory can take
                which is 336MHz. */
@@ -146,7 +92,7 @@ void setMemoryClock(unsigned int frequency)
                        frequency = MHz(336);
 
                /* Calculate the divisor */
-               divisor = (unsigned int) roundedDiv(getChipClock(), frequency);
+               divisor = roundedDiv(get_mxclk_freq(), frequency);
 
                /* Set the corresponding divisor in the register. */
                ulReg = PEEK32(CURRENT_GATE);
@@ -170,7 +116,6 @@ void setMemoryClock(unsigned int frequency)
        }
 }
 
-
 /*
  * This function set up the master clock (MCLK).
  *
@@ -179,14 +124,14 @@ void setMemoryClock(unsigned int frequency)
  * NOTE:
  *      The maximum frequency the engine can run is 168MHz.
  */
-void setMasterClock(unsigned int frequency)
+static void setMasterClock(unsigned int frequency)
 {
        unsigned int ulReg, divisor;
-#if 1
+
        /* Cheok_0509: For SM750LE, the memory clock is fixed. Nothing to set. */
        if (getChipType() == SM750LE)
                return;
-#endif
+
        if (frequency) {
                /* Set the frequency to the maximum frequency that the SM750 engine can
                run, which is about 190 MHz. */
@@ -194,7 +139,7 @@ void setMasterClock(unsigned int frequency)
                        frequency = MHz(190);
 
                /* Calculate the divisor */
-               divisor = (unsigned int) roundedDiv(getChipClock(), frequency);
+               divisor = roundedDiv(get_mxclk_freq(), frequency);
 
                /* Set the corresponding divisor in the register. */
                ulReg = PEEK32(CURRENT_GATE);
@@ -218,7 +163,6 @@ void setMasterClock(unsigned int frequency)
                }
 }
 
-
 unsigned int ddk750_getVMSize(void)
 {
        unsigned int reg;
@@ -226,7 +170,7 @@ unsigned int ddk750_getVMSize(void)
 
        /* sm750le only use 64 mb memory*/
        if (getChipType() == SM750LE)
-               return MB(64);
+               return SZ_64M;
 
        /* for 750,always use power mode0*/
        reg = PEEK32(MODE0_GATE);
@@ -237,38 +181,25 @@ unsigned int ddk750_getVMSize(void)
        reg = FIELD_GET(PEEK32(MISC_CTRL), MISC_CTRL, LOCALMEM_SIZE);
        switch (reg) {
        case MISC_CTRL_LOCALMEM_SIZE_8M:
-               data = MB(8);  break; /* 8  Mega byte */
+               data = SZ_8M;  break; /* 8  Mega byte */
        case MISC_CTRL_LOCALMEM_SIZE_16M:
-               data = MB(16); break; /* 16 Mega byte */
+               data = SZ_16M; break; /* 16 Mega byte */
        case MISC_CTRL_LOCALMEM_SIZE_32M:
-               data = MB(32); break; /* 32 Mega byte */
+               data = SZ_32M; break; /* 32 Mega byte */
        case MISC_CTRL_LOCALMEM_SIZE_64M:
-               data = MB(64); break; /* 64 Mega byte */
+               data = SZ_64M; break; /* 64 Mega byte */
        default:
                data = 0;
                break;
        }
        return data;
-
 }
 
 int ddk750_initHw(initchip_param_t *pInitParam)
 {
-
        unsigned int ulReg;
-#if 0
-       //move the code to map regiter function.
-       if (getChipType() == SM718) {
-               /* turn on big endian bit*/
-               ulReg = PEEK32(0x74);
-               /* now consider register definition in a big endian pattern*/
-               POKE32(0x74, ulReg|0x80000000);
-       }
 
-#endif
-
-
-       if (pInitParam->powerMode != 0 )
+       if (pInitParam->powerMode != 0)
                pInitParam->powerMode = 0;
        setPowerMode(pInitParam->powerMode);
 
@@ -285,7 +216,7 @@ int ddk750_initHw(initchip_param_t *pInitParam)
                ulReg = FIELD_SET(ulReg, VGA_CONFIGURATION, MODE, GRAPHIC);
                POKE32(VGA_CONFIGURATION, ulReg);
        } else {
-#if defined(__i386__) || defined( __x86_64__)
+#if defined(__i386__) || defined(__x86_64__)
                /* set graphic mode via IO method */
                outb_p(0x88, 0x3d4);
                outb_p(0x06, 0x3d5);
@@ -333,37 +264,6 @@ int ddk750_initHw(initchip_param_t *pInitParam)
                ulReg = FIELD_SET(ulReg, ALPHA_DISPLAY_CTRL, PLANE, DISABLE);
                POKE32(ALPHA_DISPLAY_CTRL, ulReg);
 
-#if 0
-               /* Disable LCD hardware cursor, if a former application left it on */
-               ulReg = PEEK32(PANEL_HWC_ADDRESS);
-               ulReg = FIELD_SET(ulReg, PANEL_HWC_ADDRESS, ENABLE, DISABLE);
-               POKE32(PANEL_HWC_ADDRESS, ulReg);
-
-               /* Disable CRT hardware cursor, if a former application left it on */
-               ulReg = PEEK32(CRT_HWC_ADDRESS);
-               ulReg = FIELD_SET(ulReg, CRT_HWC_ADDRESS, ENABLE, DISABLE);
-               POKE32(CRT_HWC_ADDRESS, ulReg);
-
-               /* Disable ZV Port 0, if a former application left it on */
-               ulReg = PEEK32(ZV0_CAPTURE_CTRL);
-               ulReg = FIELD_SET(ulReg, ZV0_CAPTURE_CTRL, CAP, DISABLE);
-               POKE32(ZV0_CAPTURE_CTRL, ulReg);
-
-               /* Disable ZV Port 1, if a former application left it on */
-               ulReg = PEEK32(ZV1_CAPTURE_CTRL);
-               ulReg = FIELD_SET(ulReg, ZV1_CAPTURE_CTRL, CAP, DISABLE);
-               POKE32(ZV1_CAPTURE_CTRL, ulReg);
-
-               /* Disable ZV Port Power, if a former application left it on */
-               enableZVPort(0);
-               /* Disable DMA Channel, if a former application left it on */
-               ulReg = PEEK32(DMA_ABORT_INTERRUPT);
-               ulReg = FIELD_SET(ulReg, DMA_ABORT_INTERRUPT, ABORT_1, ABORT);
-               POKE32(DMA_ABORT_INTERRUPT, ulReg);
-
-               /* Disable i2c */
-               enableI2C(0);
-#endif
                /* Disable DMA Channel, if a former application left it on */
                ulReg = PEEK32(DMA_ABORT_INTERRUPT);
                ulReg = FIELD_SET(ulReg, DMA_ABORT_INTERRUPT, ABORT_1, ABORT);
@@ -378,17 +278,6 @@ int ddk750_initHw(initchip_param_t *pInitParam)
        return 0;
 }
 
-#if 0
-
-unsigned int absDiff(unsigned int a, unsigned int b)
-{
-       if ( a > b )
-               return(a - b);
-       else
-               return(b - a);
-}
-
-#endif
 /*
        monk liu @ 4/6/2011:
                   re-write the calculatePLL function of ddk750.
@@ -407,196 +296,64 @@ unsigned int absDiff(unsigned int a, unsigned int b)
 */
 unsigned int calcPllValue(unsigned int request_orig, pll_value_t *pll)
 {
-       /* used for primary and secondary channel pixel clock pll */
-       static pllcalparam xparm_PIXEL[] = {
-               /* 2^0 = 1*/                    {0, 0, 0, 1},
-               /* 2^ 1 =2*/                    {1, 0, 1, 2},
-               /* 2^ 2  = 4*/          {2, 0, 2, 4},
-                                                       {3, 0, 3, 8},
-                                                       {4, 1, 3, 16},
-                                                       {5, 2, 3, 32},
-               /* 2^6 = 64  */         {6, 3, 3, 64},
-                                                       };
-
-       /* used for MXCLK (chip clock) */
-       static pllcalparam xparm_MXCLK[] = {
-               /* 2^0 = 1*/                    {0, 0, 0, 1},
-               /* 2^ 1 =2*/                    {1, 0, 1, 2},
-               /* 2^ 2  = 4*/          {2, 0, 2, 4},
-                                                       {3, 0, 3, 8},
-                                                       };
-
        /* as sm750 register definition, N located in 2,15 and M located in 1,255       */
        int N, M, X, d;
-       int xcnt;
-       int miniDiff;
+       int mini_diff;
        unsigned int RN, quo, rem, fl_quo;
        unsigned int input, request;
        unsigned int tmpClock, ret;
-       pllcalparam * xparm;
+       const int max_OD = 3;
+       int max_d;
 
-#if 1
        if (getChipType() == SM750LE) {
                /* SM750LE don't have prgrammable PLL and M/N values to work on.
                Just return the requested clock. */
                return request_orig;
        }
-#endif
 
        ret = 0;
-       miniDiff = ~0;
+       mini_diff = ~0;
        request = request_orig / 1000;
        input = pll->inputFreq / 1000;
 
        /* for MXCLK register , no POD provided, so need be treated differently */
-
-       if (pll->clockType != MXCLK_PLL) {
-               xparm = &xparm_PIXEL[0];
-               xcnt = sizeof(xparm_PIXEL)/sizeof(xparm_PIXEL[0]);
-       } else {
-               xparm = &xparm_MXCLK[0];
-               xcnt = sizeof(xparm_MXCLK)/sizeof(xparm_MXCLK[0]);
-       }
-
+       if (pll->clockType == MXCLK_PLL)
+               max_d = 3;
 
        for (N = 15; N > 1; N--) {
                /* RN will not exceed maximum long if @request <= 285 MHZ (for 32bit cpu) */
                RN = N * request;
                quo = RN / input;
                rem = RN % input;/* rem always small than 14318181 */
-               fl_quo = (rem * 10000 /input);
+               fl_quo = (rem * 10000 / input);
 
-               for (d = xcnt - 1; d >= 0; d--) {
-                       X = xparm[d].value;
-                       M = quo*X;
+               for (d = max_d; d >= 0; d--) {
+                       X = (1 << d);
+                       M = quo * X;
                        M += fl_quo * X / 10000;
                        /* round step */
-                       M += (fl_quo*X % 10000)>5000?1:0;
+                       M += (fl_quo * X % 10000) > 5000 ? 1 : 0;
                        if (M < 256 && M > 0) {
                                unsigned int diff;
-                               tmpClock = pll->inputFreq *M / N / X;
+
+                               tmpClock = pll->inputFreq * M / N / X;
                                diff = absDiff(tmpClock, request_orig);
-                               if (diff < miniDiff) {
+                               if (diff < mini_diff) {
                                        pll->M = M;
                                        pll->N = N;
-                                       pll->OD = xparm[d].od;
-                                       pll->POD = xparm[d].pod;
-                                       miniDiff = diff;
+                                       pll->POD = 0;
+                                       if (d > max_OD)
+                                               pll->POD = d - max_OD;
+                                       pll->OD = d - pll->POD;
+                                       mini_diff = diff;
                                        ret = tmpClock;
                                }
                        }
                }
        }
-
-       //printk("Finally:  pll->n[%lu],m[%lu],od[%lu],pod[%lu]\n",pll->N,pll->M,pll->OD,pll->POD);
        return ret;
 }
 
-unsigned int calcPllValue2(
-unsigned int ulRequestClk, /* Required pixel clock in Hz unit */
-pll_value_t *pPLL           /* Structure to hold the value to be set in PLL */
-)
-{
-       unsigned int M, N, OD, POD = 0, diff, pllClk, odPower, podPower;
-       unsigned int bestDiff = 0xffffffff; /* biggest 32 bit unsigned number */
-       unsigned int ret;
-    /* Init PLL structure to know states */
-       pPLL->M = 0;
-       pPLL->N = 0;
-       pPLL->OD = 0;
-       pPLL->POD = 0;
-
-    /* Sanity check: None at the moment */
-
-    /* Convert everything in Khz range in order to avoid calculation overflow */
-       pPLL->inputFreq /= 1000;
-       ulRequestClk /= 1000;
-
-#ifndef VALIDATION_CHIP
-    /* The maximum of post divider is 8. */
-       for (POD = 0; POD <= 3; POD++)
-#endif
-               {
-
-#ifndef VALIDATION_CHIP
-       /* MXCLK_PLL does not have post divider. */
-       if ((POD > 0) && (pPLL->clockType == MXCLK_PLL))
-               break;
-#endif
-
-       /* Work out 2 to the power of POD */
-       podPower = twoToPowerOfx(POD);
-
-       /* OD has only 2 bits [15:14] and its value must between 0 to 3 */
-       for (OD = 0; OD <= 3; OD++) {
-               /* Work out 2 to the power of OD */
-               odPower = twoToPowerOfx(OD);
-
-#ifdef VALIDATION_CHIP
-       if (odPower > 4)
-               podPower = 4;
-       else
-               podPower = odPower;
-#endif
-
-               /* N has 4 bits [11:8] and its value must between 2 and 15.
-               The N == 1 will behave differently --> Result is not correct. */
-       for (N = 2; N <= 15; N++) {
-               /* The formula for PLL is ulRequestClk = inputFreq * M / N / (2^OD)
-               In the following steps, we try to work out a best M value given the others are known.
-               To avoid decimal calculation, we use 1000 as multiplier for up to 3 decimal places of accuracy.
-               */
-               M = ulRequestClk * N * odPower * 1000 / pPLL->inputFreq;
-               M = roundedDiv(M, 1000);
-
-               /* M field has only 8 bits, reject value bigger than 8 bits */
-               if (M < 256) {
-                       /* Calculate the actual clock for a given M & N */
-                       pllClk = pPLL->inputFreq * M / N / odPower / podPower;
-
-                       /* How much are we different from the requirement */
-                       diff = absDiff(pllClk, ulRequestClk);
-
-                       if (diff < bestDiff) {
-                               bestDiff = diff;
-
-                               /* Store M and N values */
-                               pPLL->M  = M;
-                               pPLL->N  = N;
-                               pPLL->OD = OD;
-
-#ifdef VALIDATION_CHIP
-                       if (OD > 2)
-                               POD = 2;
-                       else
-                               POD = OD;
-#endif
-
-                       pPLL->POD = POD;
-                       }
-               }
-       }
-       }
-       }
-
-    /* Restore input frequency from Khz to hz unit */
-//    pPLL->inputFreq *= 1000;
-       ulRequestClk *= 1000;
-       pPLL->inputFreq = DEFAULT_INPUT_CLOCK; /* Default reference clock */
-
-    /* Output debug information */
-       //DDKDEBUGPRINT((DISPLAY_LEVEL, "calcPllValue: Requested Frequency = %d\n", ulRequestClk));
-       //DDKDEBUGPRINT((DISPLAY_LEVEL, "calcPllValue: Input CLK = %dHz, M=%d, N=%d, OD=%d, POD=%d\n", pPLL->inputFreq, pPLL->M, pPLL->N, pPLL->OD, pPLL->POD));
-
-    /* Return actual frequency that the PLL can set */
-       ret = calcPLL(pPLL);
-       return ret;
-}
-
-
-
-
-
 unsigned int formatPllReg(pll_value_t *pPLL)
 {
        unsigned int ulPllReg = 0;
@@ -606,9 +363,9 @@ unsigned int formatPllReg(pll_value_t *pPLL)
        On returning a 32 bit number, the value can be applied to any PLL in the calling function.
     */
        ulPllReg =
-       FIELD_SET(  0, PANEL_PLL_CTRL, BYPASS, OFF)
-       | FIELD_SET(  0, PANEL_PLL_CTRL, POWER,  ON)
-       | FIELD_SET(  0, PANEL_PLL_CTRL, INPUT,  OSC)
+       FIELD_SET(0, PANEL_PLL_CTRL, BYPASS, OFF)
+       | FIELD_SET(0, PANEL_PLL_CTRL, POWER,  ON)
+       | FIELD_SET(0, PANEL_PLL_CTRL, INPUT,  OSC)
 #ifndef VALIDATION_CHIP
        | FIELD_VALUE(0, PANEL_PLL_CTRL, POD,    pPLL->POD)
 #endif
@@ -616,7 +373,7 @@ unsigned int formatPllReg(pll_value_t *pPLL)
        | FIELD_VALUE(0, PANEL_PLL_CTRL, N,      pPLL->N)
        | FIELD_VALUE(0, PANEL_PLL_CTRL, M,      pPLL->M);
 
-    return ulPllReg;
+       return ulPllReg;
 }