sm501 patches
Subsystems (2)
cover sm501 patches
Here are some cleanups to the sm501 code and support for the SM502 programmable PLL.
Signature · 3 lines
Ville Syrj������l������ [email protected] http://www.sci.fi/~syrjala/
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Linux-fbdev-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-fbdev-devel
PATCH 1/7 sm501fb: Direct color visual does not work
The sm501fb palette code clearly does not handle direct color so change the driver to use true color visual for 16bpp.
--- drivers/video/sm501fb.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-)
drivers/video/sm501fb.c +3 -1
@@ -397,7 +397,7 @@ static int sm501fb_set_par_common(struct fb_info *info,break ;case 16 : - info->fix.visual =FB_VISUAL_DIRECTCOLOR ; + info->fix.visual =FB_VISUAL_TRUECOLOR ;break ;case 32 :
@@ -613,6 +613,7 @@ static int sm501fb_set_par_crt(struct fb_info *info)case 16 : control |=SM501_DC_CRT_CONTROL_16BPP ; +sm501fb_setup_gamma (fbi,SM501_DC_CRT_PALETTE );break ;case 32 :
@@ -741,6 +742,7 @@ static int sm501fb_set_par_pnl(struct fb_info *info)case 16 : control |=SM501_DC_PANEL_CONTROL_16BPP ; +sm501fb_setup_gamma (fbi,SM501_DC_PANEL_PALETTE );break ;case 32 :
Signature · 7 lines
1.5.2.5 ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Re: [PATCH 1/7] sm501fb: Direct color visual does not work
Quoted 4 lines · Ville Syrjala
The sm501fb palette code clearly does not handle direct color so change the driver to use true color visual for 16bpp.
Signed-off-by Ville Syrjala <[email protected]>
Heh, I cooked up the _exact_ same patch a little while ago. Sorry for the late reply.
As Ville says, it's pretty obvious that direct color is not handled in sm501fb_setcolreg(). WIthout this patch 16bpp fbcon ends up all black apart from just a blinking cursor. X may or may work on top of this, but that's not the issue here. fbcon doesn't display any text without this patch. Just boot the kernel with 16bpp mode to reproduce with 2.6.24-rc6.
Please pick up this patch. Thank you.
/ magnus
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
PATCH 2/7 sm501fb: RGB offsets are reversed in 16bpp modes
In reply to Ville SyrjalaThe RGB offsets were reversed in 16bpp modes. Simply trying to reverse the offsets when endianness differs is clearly the wrong thing to do but that is an issue for another patch.
--- drivers/video/sm501fb.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-)
drivers/video/sm501fb.c +4 -4
@@ -286,13 +286,13 @@ static int sm501fb_check_var(struct fb_var_screeninfo *var,case 16 :if (sm->pdata->flags &SM501_FBPD_SWAP_FB_ENDIAN ) { - var->red.offset =11 ; - var->green.offset =5 ; - var->blue.offset =0 ; - }else { var->blue.offset =11 ; var->green.offset =5 ; var->red.offset =0 ; + }else { + var->red.offset =11 ; + var->green.offset =5 ; + var->blue.offset =0 ; } var->red.length =5 ;
Signature · 7 lines
1.5.2.5 ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
PATCH 3/7 sm501fb: Set transp.offset to 0 in 8bpp and 16bpp modes
In reply to Ville SyrjalaEven though it may not be strictly necessary transp.offset should probably be 0 when alpha channel is not available.
--- drivers/video/sm501fb.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/video/sm501fb.c +2 -0
@@ -281,6 +281,7 @@ static int sm501fb_check_var(struct fb_var_screeninfo *var, var->blue.length = var->bits_per_pixel; var->blue.offset =0 ; var->transp.length =0 ; + var->transp.offset =0 ;break ;
@@ -294,6 +295,7 @@ static int sm501fb_check_var(struct fb_var_screeninfo *var, var->green.offset =5 ; var->blue.offset =0 ; } + var->transp.offset =0 ; var->red.length =5 ; var->green.length =6 ;
Signature · 7 lines
1.5.2.5 ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
PATCH 4/7 sm501fb: Fix timing limits
In reply to Ville SyrjalaVertical sync height register can only hold 6 bits. Fix the hsync start test to use > instead of >=. Also add a few clarifying comments.
--- drivers/video/sm501fb.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-)
drivers/video/sm501fb.c +4 -2
@@ -237,12 +237,14 @@ static int sm501fb_check_var(struct fb_var_screeninfo *var,/* check we can fit these values into the registers */ -if (var->hsync_len >255 || var->vsync_len >255 ) +if (var->hsync_len >255 || var->vsync_len >63 )return -EINVAL ; -if ((var->xres + var->right_margin) >=4096 ) +/* hdisplay end and hsync start */ +if ((var->xres + var->right_margin) >4096 )return -EINVAL ; +/* vdisplay end and vsync start */ if ((var->yres + var->lower_margin) >2048 )return -EINVAL ;
Signature · 7 lines
1.5.2.5 ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
PATCH 5/7 sm501: Remove a duplicated table
In reply to Ville Syrjalamisc_div is a subset of px_div so eliminate the smaller table.
--- drivers/mfd/sm501.c | 45 +++++++++++++-------------------------------- 1 files changed, 13 insertions(+), 32 deletions(-)
drivers/mfd/sm501.c +13 -32
@@ -53,26 +53,7 @@ struct sm501_devdata {#define MHZ (1000 * 1000)#ifdef DEBUG -static const unsigned int misc_div[] = { - [0 ] =1 , - [1 ] =2 , - [2 ] =4 , - [3 ] =8 , - [4 ] =16 , - [5 ] =32 , - [6 ] =64 , - [7 ] =128 , - [8 ] =3 , - [9 ] =6 , - [10 ] =12 , - [11 ] =24 , - [12 ] =48 , - [13 ] =96 , - [14 ] =192 , - [15 ] =384 , -}; - -static const unsigned int px_div[] = { +static const unsigned int div_tab[] = { [0 ] =1 , [1 ] =2 , [2] = 4,
@@ -101,12 +82,12 @@ static const unsigned int px_div[] = {static unsigned long decode_div (unsigned long pll2,unsigned long val,unsigned int lshft,unsigned int selbit, -unsigned long mask,const unsigned int *dtab) +unsigned long mask) {if (val & selbit) pll2 =288 *MHZ ; -return pll2 / dtab[(val >> lshft) & mask]; +return pll2 / div_tab[(val >> lshft) & mask]; }#define fmt_freq (x) ((x) / MHZ), ((x) % MHZ), (x)
@@ -141,10 +122,10 @@ static void sm501_dump_clk(struct sm501_devdata *sm) } sdclk0 = (misct & (1 <<12 )) ? pll2 :288 *MHZ ; - sdclk0 /= misc_div[((misct >>8 ) &0xf )]; + sdclk0 /= div_tab[((misct >>8 ) &0xf )]; sdclk1 = (misct & (1 <<20 )) ? pll2 :288 *MHZ ; - sdclk1 /= misc_div[((misct >>16 ) &0xf )]; + sdclk1 /= div_tab[((misct >>16 ) &0xf )];dev_dbg (sm->dev,"MISCT=%08lx, PM0=%08lx, PM1=%08lx\n" , misct, pm0, pm1);
@@ -158,19 +139,19 @@ static void sm501_dump_clk(struct sm501_devdata *sm)"P2 %ld.%ld MHz (%ld), V2 %ld.%ld (%ld), " x"M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n" , (pmc &3 ) ==0 ?'*' :'-' , -fmt_freq (decode_div (pll2, pm0,24 ,1 <<29 ,31 , px_div)), -fmt_freq (decode_div (pll2, pm0,16 ,1 <<20 ,15 , misc_div)), -fmt_freq (decode_div (pll2, pm0,8 ,1 <<12 ,15 , misc_div)), - fmt_freq(decode_div(pll2, pm0, 0, 1<<4, 15, misc_div))); +fmt_freq (decode_div (pll2, pm0,24 ,1 <<29 ,31 )), +fmt_freq (decode_div (pll2, pm0,16 ,1 <<20 ,15 )), +fmt_freq (decode_div (pll2, pm0,8 ,1 <<12 ,15 )), + fmt_freq(decode_div(pll2, pm0, 0, 1<<4, 15)));dev_dbg (sm->dev,"PM1[%c]: " "P2 %ld.%ld MHz (%ld), V2 %ld.%ld (%ld), " "M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n" , (pmc &3 ) ==1 ?'*' :'-' , -fmt_freq (decode_div (pll2, pm1,24 ,1 <<29 ,31 , px_div)), -fmt_freq (decode_div (pll2, pm1,16 ,1 <<20 ,15 , misc_div)), -fmt_freq (decode_div (pll2, pm1,8 ,1 <<12 ,15 , misc_div)), -fmt_freq (decode_div (pll2, pm1,0 ,1 <<4 ,15 , misc_div))); +fmt_freq (decode_div (pll2, pm1,24 ,1 <<29 ,31 )), +fmt_freq (decode_div (pll2, pm1,16 ,1 <<20 ,15 )), +fmt_freq (decode_div (pll2, pm1,8 ,1 <<12 ,15 )), +fmt_freq (decode_div (pll2, pm1,0 ,1 <<4 ,15 ))); }static void sm501_dump_regs (struct sm501_devdata *sm)
Signature · 7 lines
1.5.2.5 ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
PATCH 6/7 sm501: Remove a misplaced x character
In reply to Ville Syrjalasm501.c doesn't compile with debug enabled due to a misplaced x character.
--- drivers/mfd/sm501.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/mfd/sm501.c +1 -1
@@ -137,7 +137,7 @@ static void sm501_dump_clk(struct sm501_devdata *sm) dev_dbg(sm->dev, "PM0[%c]: " "P2 %ld.%ld MHz (%ld), V2 %ld.%ld (%ld), " -x "M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n", + "M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n", (pmc & 3 ) == 0 ? '*' : '-', fmt_freq(decode_div(pll2, pm0, 24, 1<<29, 31)), fmt_freq(decode_div(pll2, pm0, 16, 1<<20, 15)),
Signature · 7 lines
1.5.2.5 ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Re: [PATCH 6/7] sm501: Remove a misplaced x character
Quoted 1 line · Ville Syrjala
sm501.cdoesn't compile with debug enabled due to a misplaced x character.
Hi, thanks but a fix for this has already been submitted.
Quoted 30 lines
Signed-off-by Ville Syrjala <[email protected]>--- drivers/mfd/sm501.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)drivers/mfd/sm501.c +1
-1@@ -137,7 +137,7 @@ static void sm501_dump_clk(struct sm501_devdata *sm) dev_dbg(sm->dev, "PM0[%c]: " "P2 %ld.%ld MHz (%ld), V2 %ld.%ld (%ld), " -x "M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n", + "M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n", (pmc & 3 ) == 0 ? '*' : '-', fmt_freq(decode_div(pll2, pm0, 24, 1<<29, 31)), fmt_freq(decode_div(pll2, pm0, 16, 1<<20, 15)),Signature · 11 lines
1.5.2.5 ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Linux-fbdev-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-fbdev-devel
Signature · 8 lines
Ben ([email protected], http://www.fluff.org/) 'a smiley only costs 4 bytes' ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
PATCH 7/7 sm501: Add support for the SM502 programmable PLL
In reply to Ville SyrjalaSM502 has a programmable PLL which can provide the panel pixel clock instead of the 288MHz and 336MHz PLLs.
--- drivers/mfd/sm501.c | 163 ++++++++++++++++++++++++++++++++++---------- include/linux/sm501-regs.h | 3 + include/linux/sm501.h | 3 +- 3 files changed, 133 insertions(+), 36 deletions(-)
drivers/mfd/sm501.c +128 -35
@@ -48,6 +48,7 @@ struct sm501_devdata {unsigned int pdev_id;unsigned int irq;void __iomem *regs; +unsigned int rev; };#define MHZ (1000 * 1000)
@@ -417,46 +418,108 @@ struct sm501_clock {unsigned long mclk;int divider;int shift; +unsigned int m, n, k; }; +/* sm501_calc_clock +* +* Calculates the nearest discrete clock frequency that +* can be achieved with the specified input clock. +* the maximum divisor is 3 or 5 +*/ + +static int sm501_calc_clock (unsigned long freq, +struct sm501_clock *clock, +int max_div, +unsigned long mclk, +long *best_diff) +{ +int ret =0 ; +int divider; +int shift; +long diff; + +/* try dividers 1 and 3 for CRT and for panel, +try divider 5 for panel only.*/ + +for (divider =1 ; divider <= max_div; divider +=2 ) { +/* try all 8 shift values.*/ +for (shift =0 ; shift <8 ; shift++) { +/* Calculate difference to requested clock */ + diff =sm501fb_round_div (mclk, divider << shift) - freq; +if (diff <0 ) + diff = -diff; + +/* If it is less than the current, use it */ +if (diff < *best_diff) { + *best_diff = diff; + + clock->mclk = mclk; + clock->divider = divider; + clock->shift = shift; + ret =1 ; + } + } + } + +return ret; +} + +/* sm501_calc_pll +* +* Calculates the nearest discrete clock frequency that can be +* achieved using the programmable PLL. +* the maximum divisor is 3 or 5 +*/ + +static unsigned long sm501_calc_pll (unsigned long freq, +struct sm501_clock *clock, +int max_div) +{ +unsigned long mclk; +unsigned int m, n, k; +long best_diff =999999999 ; + +/* +* The SM502 datasheet doesn't specify the min/max values for M and N. +* N = 1 at least doesn't work in practice. +*/ +for (m =2 ; m <=255 ; m++) { +for (n =2 ; n <=127 ; n++) { +for (k =0 ; k <=1 ; k++) { + mclk = (24000000UL * m / n) >> k; + +if (sm501_calc_clock (freq, clock, max_div, + mclk, &best_diff)) { + clock->m = m; + clock->n = n; + clock->k = k; + } + } + } + } + +/* Return best clock. */ +return clock->mclk / (clock->divider << clock->shift); +} +/* sm501_select_clock * -* selects nearest discrete clock frequency the SM501 can achive +* Calculates the nearest discrete clock frequency that can be +* achieved using the 288MHz and 336MHz PLLs. * the maximum divisor is 3 or 5 */ +static unsigned long sm501_select_clock (unsigned long freq,struct sm501_clock *clock,int max_div) {unsigned long mclk; -int divider; -int shift; -long diff;long best_diff =999999999 ;/* Try 288MHz and 336MHz clocks. */ for (mclk =288000000 ; mclk <=336000000 ; mclk +=48000000 ) { -/* try dividers 1 and 3 for CRT and for panel, -try divider 5 for panel only.*/ - -for (divider =1 ; divider <= max_div; divider +=2 ) { -/* try all 8 shift values.*/ -for (shift =0 ; shift <8 ; shift++) { -/* Calculate difference to requested clock */ - diff =sm501fb_round_div (mclk, divider << shift) - freq; -if (diff <0 ) - diff = -diff; - -/* If it is less than the current, use it */ -if (diff < best_diff) { - best_diff = diff; - - clock->mclk = mclk; - clock->divider = divider; - clock->shift = shift; - } - } - } +sm501_calc_clock (freq, clock, max_div, mclk, &best_diff); }/* Return best clock. */
@@ -478,6 +541,7 @@ unsigned long sm501_set_clock(struct device *dev,unsigned long gate =readl (sm->regs +SM501_CURRENT_GATE );unsigned long clock =readl (sm->regs +SM501_CURRENT_CLOCK );unsigned char reg; +unsigned int pll_reg =0 ;unsigned long sm501_freq;/* the actual frequency acheived */ struct sm501_clock to;
@@ -492,14 +556,28 @@ unsigned long sm501_set_clock(struct device *dev,* requested frequency the value must be multiplied by * 2. This clock also has an additional pre divisor */ - sm501_freq = (sm501_select_clock (2 * req_freq, &to,5 ) /2 ); - reg=to.shift &0x07 ;/* bottom 3 bits are shift */ -if (to.divider ==3 ) - reg |=0x08 ;/* /3 divider required */ -else if (to.divider ==5 ) - reg |=0x10 ;/* /5 divider required */ -if (to.mclk !=288000000 ) - reg |=0x20 ;/* which mclk pll is source */ +if (sm->rev >=0xC0 ) { +/* SM502 -> use the programmable PLL */ + sm501_freq = (sm501_calc_pll (2 * req_freq, + &to,5 ) /2 ); + reg=to.shift &0x07 ;/* bottom 3 bits are shift */ +if (to.divider ==3 ) + reg |=0x08 ;/* /3 divider required */ +else if (to.divider ==5 ) + reg |=0x10 ;/* /5 divider required */ + reg |=0x40 ;/* select the programmable PLL */ + pll_reg =0x20000 | (to.k <<15 ) | (to.n <<8 ) | to.m; + }else { + sm501_freq = (sm501_select_clock (2 * req_freq, + &to,5 ) /2 ); + reg=to.shift &0x07 ;/* bottom 3 bits are shift */ +if (to.divider ==3 ) + reg |=0x08 ;/* /3 divider required */ +else if (to.divider ==5 ) + reg |=0x10 ;/* /5 divider required */ +if (to.mclk !=288000000 ) + reg |=0x20 ;/* which mclk pll is source */ + }break ;case SM501_CLOCK_V2XCLK :
@@ -560,6 +638,10 @@ unsigned long sm501_set_clock(struct device *dev, }writel (mode, sm->regs +SM501_POWER_MODE_CONTROL ); + +if (pll_reg) +writel (pll_reg, sm->regs +SM501_PROGRAMMABLE_PLL_CONTROL ); +sm501_sync_regs (sm); dev_info(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n",
@@ -580,15 +662,24 @@ EXPORT_SYMBOL_GPL(sm501_set_clock);* finds the closest available frequency for a given clock */ -unsigned long sm501_find_clock (int clksrc, +unsigned long sm501_find_clock (struct device *dev, +int clksrc,unsigned long req_freq) { +struct sm501_devdata *sm =dev_get_drvdata (dev);unsigned long sm501_freq;/* the frequency achiveable by the 501 */ struct sm501_clock to;switch (clksrc) {case SM501_CLOCK_P2XCLK : - sm501_freq = (sm501_select_clock (2 * req_freq, &to,5 ) /2 ); +if (sm->rev >=0xC0 ) { +/* SM502 -> use the programmable PLL */ + sm501_freq = (sm501_calc_pll (2 * req_freq, + &to,5 ) /2 ); + }else { + sm501_freq = (sm501_select_clock (2 * req_freq, + &to,5 ) /2 ); + }break ;case SM501_CLOCK_V2XCLK :
@@ -895,6 +986,8 @@ static int sm501_init_dev(struct sm501_devdata *sm)dev_info (sm->dev,"SM501 At %p: Version %08lx, %ld Mb, IRQ %d\n" , sm->regs, devid, (unsigned long )mem_avail >>20 , sm->irq); + sm->rev = devid &SM501_DEVICEID_REVMASK ; +sm501_dump_gate (sm); ret =device_create_file (sm->dev, &dev_attr_dbg_regs);
include/linux/sm501-regs.h +3 -0
@@ -129,11 +129,14 @@#define SM501_DEVICEID_SM501 (0x05010000)#define SM501_DEVICEID_IDMASK (0xffff0000) +#define SM501_DEVICEID_REVMASK (0x000000ff)#define SM501_PLLCLOCK_COUNT (0x000064)#define SM501_MISC_TIMING (0x000068)#define SM501_CURRENT_SDRAM_CLOCK (0x00006C) +#define SM501_PROGRAMMABLE_PLL_CONTROL (0x000074) +/* GPIO base */ #define SM501_GPIO (0x010000)#define SM501_GPIO_DATA_LOW (0x00)
include/linux/sm501.h +2 -1
@@ -24,7 +24,8 @@ extern int sm501_unit_power(struct device *dev,extern unsigned long sm501_set_clock (struct device *dev,int clksrc,unsigned long freq); -extern unsigned long sm501_find_clock (int clksrc,unsigned long req_freq); +extern unsigned long sm501_find_clock (struct device *dev, +int clksrc,unsigned long req_freq);/* sm501_misc_control *
Signature · 7 lines
1.5.2.5 ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Quoted 2 lines · Ville Syrjala
Here are some cleanups to the sm501 code and support for the SM502 programmable PLL.
Those looks reasonable, other than the debug patch which has already been taken by akpm. I'll try and sort out testing the SM502 changes now I have access to an SM502 device.
Signature · 10 lines
Ben ([email protected], http://www.fluff.org/) 'a smiley only costs 4 bytes' ------------------------------------------------------------------------- SF.Net email is sponsored by: Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://sourceforge.net/services/buy/index.php