diff options
author | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-11 10:41:07 +0300 |
---|---|---|
committer | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-13 08:17:18 +0300 |
commit | e09b41010ba33a20a87472ee821fa407a5b8da36 (patch) | |
tree | d10dc367189862e7ca5c592f033dc3726e1df4e3 /kernel/drivers/staging/sm750fb/ddk750_chip.c | |
parent | f93b97fd65072de626c074dbe099a1fff05ce060 (diff) |
These changes are the raw update to linux-4.4.6-rt14. Kernel sources
are taken from kernel.org, and rt patch from the rt wiki download page.
During the rebasing, the following patch collided:
Force tick interrupt and get rid of softirq magic(I70131fb85).
Collisions have been removed because its logic was found on the
source already.
Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769
Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'kernel/drivers/staging/sm750fb/ddk750_chip.c')
-rw-r--r-- | kernel/drivers/staging/sm750fb/ddk750_chip.c | 349 |
1 files changed, 53 insertions, 296 deletions
diff --git a/kernel/drivers/staging/sm750fb/ddk750_chip.c b/kernel/drivers/staging/sm750fb/ddk750_chip.c index 7b28328c9..0331d3445 100644 --- a/kernel/drivers/staging/sm750fb/ddk750_chip.c +++ b/kernel/drivers/staging/sm750fb/ddk750_chip.c @@ -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; } |