Loading drivers/video/Kconfig +11 −0 Original line number Diff line number Diff line Loading @@ -1607,6 +1607,17 @@ config FB_VIA_DIRECT_PROCFS correct output device configuration. Its use is strongly discouraged. config FB_VIA_X_COMPATIBILITY bool "X server compatibility" depends on FB_VIA default n help This option reduces the functionality (power saving, ...) of the framebuffer to avoid negative impact on the OpenChrome X server. If you use any X server other than fbdev you should enable this otherwise it should be safe to disable it and allow using all features. endif config FB_NEOMAGIC Loading drivers/video/via/Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -6,4 +6,4 @@ obj-$(CONFIG_FB_VIA) += viafb.o viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o \ via_utility.o vt1636.o global.o tblDPASetting.o viamode.o \ via-core.o via-gpio.o via_modesetting.o via-core.o via-gpio.o via_modesetting.o via_clock.o drivers/video/via/hw.c +144 −385 Original line number Diff line number Diff line Loading @@ -22,273 +22,82 @@ #include <linux/via-core.h> #include <asm/olpc.h> #include "global.h" static struct pll_config cle266_pll_config[] = { {19, 4, 0}, {26, 5, 0}, {28, 5, 0}, {31, 5, 0}, {33, 5, 0}, {55, 5, 0}, {102, 5, 0}, {53, 6, 0}, {92, 6, 0}, {98, 6, 0}, {112, 6, 0}, {41, 7, 0}, {60, 7, 0}, {99, 7, 0}, {100, 7, 0}, {83, 8, 0}, {86, 8, 0}, {108, 8, 0}, {87, 9, 0}, {118, 9, 0}, {95, 12, 0}, {115, 12, 0}, {108, 13, 0}, {83, 17, 0}, {67, 20, 0}, {86, 20, 0}, {98, 20, 0}, {121, 24, 0}, {99, 29, 0}, {33, 3, 1}, {15, 4, 1}, {23, 4, 1}, {37, 5, 1}, {83, 5, 1}, {85, 5, 1}, {94, 5, 1}, {103, 5, 1}, {109, 5, 1}, {113, 5, 1}, {121, 5, 1}, {82, 6, 1}, {31, 7, 1}, {55, 7, 1}, {84, 7, 1}, {83, 8, 1}, {76, 9, 1}, {127, 9, 1}, {33, 4, 2}, {75, 4, 2}, {119, 4, 2}, {121, 4, 2}, {91, 5, 2}, {118, 5, 2}, {83, 6, 2}, {109, 6, 2}, {90, 7, 2}, {93, 2, 3}, {53, 3, 3}, {73, 4, 3}, {89, 4, 3}, {105, 4, 3}, {117, 4, 3}, {101, 5, 3}, {121, 5, 3}, {127, 5, 3}, {99, 7, 3} #include "via_clock.h" static struct pll_limit cle266_pll_limits[] = { {19, 19, 4, 0}, {26, 102, 5, 0}, {53, 112, 6, 0}, {41, 100, 7, 0}, {83, 108, 8, 0}, {87, 118, 9, 0}, {95, 115, 12, 0}, {108, 108, 13, 0}, {83, 83, 17, 0}, {67, 98, 20, 0}, {121, 121, 24, 0}, {99, 99, 29, 0}, {33, 33, 3, 1}, {15, 23, 4, 1}, {37, 121, 5, 1}, {82, 82, 6, 1}, {31, 84, 7, 1}, {83, 83, 8, 1}, {76, 127, 9, 1}, {33, 121, 4, 2}, {91, 118, 5, 2}, {83, 109, 6, 2}, {90, 90, 7, 2}, {93, 93, 2, 3}, {53, 53, 3, 3}, {73, 117, 4, 3}, {101, 127, 5, 3}, {99, 99, 7, 3} }; static struct pll_config k800_pll_config[] = { {22, 2, 0}, {28, 3, 0}, {81, 3, 1}, {85, 3, 1}, {98, 3, 1}, {112, 3, 1}, {86, 4, 1}, {166, 4, 1}, {109, 5, 1}, {113, 5, 1}, {121, 5, 1}, {131, 5, 1}, {143, 5, 1}, {153, 5, 1}, {66, 3, 2}, {68, 3, 2}, {95, 3, 2}, {106, 3, 2}, {116, 3, 2}, {93, 4, 2}, {119, 4, 2}, {121, 4, 2}, {133, 4, 2}, {137, 4, 2}, {117, 5, 2}, {118, 5, 2}, {120, 5, 2}, {124, 5, 2}, {132, 5, 2}, {137, 5, 2}, {141, 5, 2}, {166, 5, 2}, {170, 5, 2}, {191, 5, 2}, {206, 5, 2}, {208, 5, 2}, {30, 2, 3}, {69, 3, 3}, {82, 3, 3}, {83, 3, 3}, {109, 3, 3}, {114, 3, 3}, {125, 3, 3}, {89, 4, 3}, {103, 4, 3}, {117, 4, 3}, {126, 4, 3}, {150, 4, 3}, {161, 4, 3}, {121, 5, 3}, {127, 5, 3}, {131, 5, 3}, {134, 5, 3}, {148, 5, 3}, {169, 5, 3}, {172, 5, 3}, {182, 5, 3}, {195, 5, 3}, {196, 5, 3}, {208, 5, 3}, {66, 2, 4}, {85, 3, 4}, {141, 4, 4}, {146, 4, 4}, {161, 4, 4}, {177, 5, 4} static struct pll_limit k800_pll_limits[] = { {22, 22, 2, 0}, {28, 28, 3, 0}, {81, 112, 3, 1}, {86, 166, 4, 1}, {109, 153, 5, 1}, {66, 116, 3, 2}, {93, 137, 4, 2}, {117, 208, 5, 2}, {30, 30, 2, 3}, {69, 125, 3, 3}, {89, 161, 4, 3}, {121, 208, 5, 3}, {66, 66, 2, 4}, {85, 85, 3, 4}, {141, 161, 4, 4}, {177, 177, 5, 4} }; static struct pll_config cx700_pll_config[] = { {98, 3, 1}, {86, 4, 1}, {109, 5, 1}, {110, 5, 1}, {113, 5, 1}, {121, 5, 1}, {131, 5, 1}, {135, 5, 1}, {142, 5, 1}, {143, 5, 1}, {153, 5, 1}, {187, 5, 1}, {208, 5, 1}, {68, 2, 2}, {95, 3, 2}, {116, 3, 2}, {93, 4, 2}, {119, 4, 2}, {133, 4, 2}, {137, 4, 2}, {151, 4, 2}, {166, 4, 2}, {110, 5, 2}, {112, 5, 2}, {117, 5, 2}, {118, 5, 2}, {120, 5, 2}, {132, 5, 2}, {137, 5, 2}, {141, 5, 2}, {151, 5, 2}, {166, 5, 2}, {175, 5, 2}, {191, 5, 2}, {206, 5, 2}, {174, 7, 2}, {82, 3, 3}, {109, 3, 3}, {117, 4, 3}, {150, 4, 3}, {161, 4, 3}, {112, 5, 3}, {115, 5, 3}, {121, 5, 3}, {127, 5, 3}, {129, 5, 3}, {131, 5, 3}, {134, 5, 3}, {138, 5, 3}, {148, 5, 3}, {157, 5, 3}, {169, 5, 3}, {172, 5, 3}, {190, 5, 3}, {195, 5, 3}, {196, 5, 3}, {208, 5, 3}, {141, 5, 4}, {150, 5, 4}, {166, 5, 4}, {176, 5, 4}, {177, 5, 4}, {183, 5, 4}, {202, 5, 4} static struct pll_limit cx700_pll_limits[] = { {98, 98, 3, 1}, {86, 86, 4, 1}, {109, 208, 5, 1}, {68, 68, 2, 2}, {95, 116, 3, 2}, {93, 166, 4, 2}, {110, 206, 5, 2}, {174, 174, 7, 2}, {82, 109, 3, 3}, {117, 161, 4, 3}, {112, 208, 5, 3}, {141, 202, 5, 4} }; static struct pll_config vx855_pll_config[] = { {86, 4, 1}, {108, 5, 1}, {110, 5, 1}, {113, 5, 1}, {121, 5, 1}, {131, 5, 1}, {135, 5, 1}, {142, 5, 1}, {143, 5, 1}, {153, 5, 1}, {164, 5, 1}, {187, 5, 1}, {208, 5, 1}, {110, 5, 2}, {112, 5, 2}, {117, 5, 2}, {118, 5, 2}, {124, 5, 2}, {132, 5, 2}, {137, 5, 2}, {141, 5, 2}, {149, 5, 2}, {151, 5, 2}, {159, 5, 2}, {166, 5, 2}, {167, 5, 2}, {172, 5, 2}, {189, 5, 2}, {191, 5, 2}, {194, 5, 2}, {206, 5, 2}, {208, 5, 2}, {83, 3, 3}, {88, 3, 3}, {109, 3, 3}, {112, 3, 3}, {103, 4, 3}, {105, 4, 3}, {161, 4, 3}, {112, 5, 3}, {115, 5, 3}, {121, 5, 3}, {127, 5, 3}, {134, 5, 3}, {137, 5, 3}, {148, 5, 3}, {157, 5, 3}, {169, 5, 3}, {172, 5, 3}, {182, 5, 3}, {191, 5, 3}, {195, 5, 3}, {209, 5, 3}, {142, 4, 4}, {146, 4, 4}, {161, 4, 4}, {141, 5, 4}, {150, 5, 4}, {165, 5, 4}, {176, 5, 4} static struct pll_limit vx855_pll_limits[] = { {86, 86, 4, 1}, {108, 208, 5, 1}, {110, 208, 5, 2}, {83, 112, 3, 3}, {103, 161, 4, 3}, {112, 209, 5, 3}, {142, 161, 4, 4}, {141, 176, 5, 4} }; /* according to VIA Technologies these values are based on experiment */ Loading Loading @@ -713,6 +522,9 @@ static struct via_device_mapping device_mapping[] = { {VIA_LVDS2, "LVDS2"} }; /* structure with function pointers to support clock control */ static struct via_clock clock; static void load_fix_bit_crtc_reg(void); static void __devinit init_gfx_chip_info(int chip_type); static void __devinit init_tmds_chip_info(void); Loading Loading @@ -1634,69 +1446,54 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active) } static u32 cle266_encode_pll(struct pll_config pll) { return (pll.multiplier << 8) | (pll.rshift << 6) | pll.divisor; } static u32 k800_encode_pll(struct pll_config pll) { return ((pll.divisor - 2) << 16) | (pll.rshift << 10) | (pll.multiplier - 2); } static u32 vx855_encode_pll(struct pll_config pll) { return (pll.divisor << 16) | (pll.rshift << 10) | pll.multiplier; } static inline u32 get_pll_internal_frequency(u32 ref_freq, struct pll_config pll) { return ref_freq / pll.divisor * pll.multiplier; } static inline u32 get_pll_output_frequency(u32 ref_freq, struct pll_config pll) { return get_pll_internal_frequency(ref_freq, pll)>>pll.rshift; } static struct pll_config get_pll_config(struct pll_config *config, int size, static struct via_pll_config get_pll_config(struct pll_limit *limits, int size, int clk) { struct pll_config best = config[0]; struct via_pll_config cur, up, down, best = {0, 1, 0}; const u32 f0 = 14318180; /* X1 frequency */ int i; for (i = 1; i < size; i++) { if (abs(get_pll_output_frequency(f0, config[i]) - clk) < abs(get_pll_output_frequency(f0, best) - clk)) best = config[i]; int i, f; for (i = 0; i < size; i++) { cur.rshift = limits[i].rshift; cur.divisor = limits[i].divisor; cur.multiplier = clk / ((f0 / cur.divisor)>>cur.rshift); f = abs(get_pll_output_frequency(f0, cur) - clk); up = down = cur; up.multiplier++; down.multiplier--; if (abs(get_pll_output_frequency(f0, up) - clk) < f) cur = up; else if (abs(get_pll_output_frequency(f0, down) - clk) < f) cur = down; if (cur.multiplier < limits[i].multiplier_min) cur.multiplier = limits[i].multiplier_min; else if (cur.multiplier > limits[i].multiplier_max) cur.multiplier = limits[i].multiplier_max; f = abs(get_pll_output_frequency(f0, cur) - clk); if (f < abs(get_pll_output_frequency(f0, best) - clk)) best = cur; } return best; } u32 viafb_get_clk_value(int clk) static struct via_pll_config get_best_pll_config(int clk) { u32 value = 0; struct via_pll_config config; switch (viaparinfo->chip_info->gfx_chip_name) { case UNICHROME_CLE266: case UNICHROME_K400: value = cle266_encode_pll(get_pll_config(cle266_pll_config, ARRAY_SIZE(cle266_pll_config), clk)); config = get_pll_config(cle266_pll_limits, ARRAY_SIZE(cle266_pll_limits), clk); break; case UNICHROME_K800: case UNICHROME_PM800: case UNICHROME_CN700: value = k800_encode_pll(get_pll_config(k800_pll_config, ARRAY_SIZE(k800_pll_config), clk)); config = get_pll_config(k800_pll_limits, ARRAY_SIZE(k800_pll_limits), clk); break; case UNICHROME_CX700: case UNICHROME_CN750: Loading @@ -1704,92 +1501,28 @@ u32 viafb_get_clk_value(int clk) case UNICHROME_P4M890: case UNICHROME_P4M900: case UNICHROME_VX800: value = k800_encode_pll(get_pll_config(cx700_pll_config, ARRAY_SIZE(cx700_pll_config), clk)); config = get_pll_config(cx700_pll_limits, ARRAY_SIZE(cx700_pll_limits), clk); break; case UNICHROME_VX855: case UNICHROME_VX900: value = vx855_encode_pll(get_pll_config(vx855_pll_config, ARRAY_SIZE(vx855_pll_config), clk)); config = get_pll_config(vx855_pll_limits, ARRAY_SIZE(vx855_pll_limits), clk); break; } return value; return config; } /* Set VCLK*/ void viafb_set_vclock(u32 clk, int set_iga) { /* H.W. Reset : ON */ viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); if (set_iga == IGA1) { /* Change D,N FOR VCLK */ switch (viaparinfo->chip_info->gfx_chip_name) { case UNICHROME_CLE266: case UNICHROME_K400: via_write_reg(VIASR, SR46, (clk & 0x00FF)); via_write_reg(VIASR, SR47, (clk & 0xFF00) >> 8); break; case UNICHROME_K800: case UNICHROME_PM800: case UNICHROME_CN700: case UNICHROME_CX700: case UNICHROME_CN750: case UNICHROME_K8M890: case UNICHROME_P4M890: case UNICHROME_P4M900: case UNICHROME_VX800: case UNICHROME_VX855: case UNICHROME_VX900: via_write_reg(VIASR, SR44, (clk & 0x0000FF)); via_write_reg(VIASR, SR45, (clk & 0x00FF00) >> 8); via_write_reg(VIASR, SR46, (clk & 0xFF0000) >> 16); break; } } if (set_iga == IGA2) { /* Change D,N FOR LCK */ switch (viaparinfo->chip_info->gfx_chip_name) { case UNICHROME_CLE266: case UNICHROME_K400: via_write_reg(VIASR, SR44, (clk & 0x00FF)); via_write_reg(VIASR, SR45, (clk & 0xFF00) >> 8); break; case UNICHROME_K800: case UNICHROME_PM800: case UNICHROME_CN700: case UNICHROME_CX700: case UNICHROME_CN750: case UNICHROME_K8M890: case UNICHROME_P4M890: case UNICHROME_P4M900: case UNICHROME_VX800: case UNICHROME_VX855: case UNICHROME_VX900: via_write_reg(VIASR, SR4A, (clk & 0x0000FF)); via_write_reg(VIASR, SR4B, (clk & 0x00FF00) >> 8); via_write_reg(VIASR, SR4C, (clk & 0xFF0000) >> 16); break; } } struct via_pll_config config = get_best_pll_config(clk); /* H.W. Reset : OFF */ viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); /* Reset PLL */ if (set_iga == IGA1) { viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1); viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1); } if (set_iga == IGA2) { viafb_write_reg_mask(SR40, VIASR, 0x04, BIT2); viafb_write_reg_mask(SR40, VIASR, 0x00, BIT2); } if (set_iga == IGA1) clock.set_primary_pll(config); if (set_iga == IGA2) clock.set_secondary_pll(config); /* Fire! */ via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */ Loading Loading @@ -2035,7 +1768,7 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, int i; int index = 0; int h_addr, v_addr; u32 pll_D_N, clock, refresh = viafb_refresh; u32 clock, refresh = viafb_refresh; if (viafb_SAMM_ON && set_iga == IGA2) refresh = viafb_refresh1; Loading Loading @@ -2089,14 +1822,13 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, clock = crt_reg.hor_total * crt_reg.ver_total * crt_table[index].refresh_rate; pll_D_N = viafb_get_clk_value(clock); DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N); viafb_set_vclock(pll_D_N, set_iga); viafb_set_vclock(clock, set_iga); } void __devinit viafb_init_chip_info(int chip_type) { via_clock_init(&clock, chip_type); init_gfx_chip_info(chip_type); init_tmds_chip_info(); init_lvds_chip_info(); Loading Loading @@ -2584,6 +2316,33 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, get_sync(viafbinfo1)); } clock.set_engine_pll_state(VIA_STATE_ON); clock.set_primary_clock_source(VIA_CLKSRC_X1, true); clock.set_secondary_clock_source(VIA_CLKSRC_X1, true); #ifdef CONFIG_FB_VIA_X_COMPATIBILITY clock.set_primary_pll_state(VIA_STATE_ON); clock.set_primary_clock_state(VIA_STATE_ON); clock.set_secondary_pll_state(VIA_STATE_ON); clock.set_secondary_clock_state(VIA_STATE_ON); #else if (viaparinfo->shared->iga1_devices) { clock.set_primary_pll_state(VIA_STATE_ON); clock.set_primary_clock_state(VIA_STATE_ON); } else { clock.set_primary_pll_state(VIA_STATE_OFF); clock.set_primary_clock_state(VIA_STATE_OFF); } if (viaparinfo->shared->iga2_devices) { clock.set_secondary_pll_state(VIA_STATE_ON); clock.set_secondary_clock_state(VIA_STATE_ON); } else { clock.set_secondary_pll_state(VIA_STATE_OFF); clock.set_secondary_clock_state(VIA_STATE_OFF); } #endif /*CONFIG_FB_VIA_X_COMPATIBILITY*/ via_set_state(devices, VIA_STATE_ON); device_screen_on(); return 1; Loading drivers/video/via/hw.h +3 −11 Original line number Diff line number Diff line Loading @@ -732,20 +732,13 @@ struct _lcd_scaling_factor { struct _lcd_ver_scaling_factor lcd_ver_scaling_factor; }; struct pll_config { u16 multiplier; struct pll_limit { u16 multiplier_min; u16 multiplier_max; u8 divisor; u8 rshift; }; struct pll_map { u32 clk; struct pll_config cle266_pll; struct pll_config k800_pll; struct pll_config cx700_pll; struct pll_config vx855_pll; }; struct rgbLUT { u8 red; u8 green; Loading Loading @@ -935,7 +928,6 @@ void viafb_lock_crt(void); void viafb_unlock_crt(void); void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga); void viafb_write_regx(struct io_reg RegTable[], int ItemNum); u32 viafb_get_clk_value(int clk); void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active); void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ *p_gfx_dpa_setting); Loading drivers/video/via/lcd.c +2 −5 Original line number Diff line number Diff line Loading @@ -558,7 +558,7 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, int set_vres = plvds_setting_info->v_active; int panel_hres = plvds_setting_info->lcd_panel_hres; int panel_vres = plvds_setting_info->lcd_panel_vres; u32 pll_D_N, clock; u32 clock; struct display_timing mode_crt_reg, panel_crt_reg; struct crt_mode_table *panel_crt_table = NULL; struct VideoModeTable *vmode_tbl = viafb_get_mode(panel_hres, Loading Loading @@ -609,10 +609,7 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, viafb_load_FIFO_reg(set_iga, set_hres, set_vres); fill_lcd_format(); pll_D_N = viafb_get_clk_value(clock); DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N); viafb_set_vclock(pll_D_N, set_iga); viafb_set_vclock(clock, set_iga); lcd_patch_skew(plvds_setting_info, plvds_chip_info); /* If K8M800, enable LCD Prefetch Mode. */ Loading Loading
drivers/video/Kconfig +11 −0 Original line number Diff line number Diff line Loading @@ -1607,6 +1607,17 @@ config FB_VIA_DIRECT_PROCFS correct output device configuration. Its use is strongly discouraged. config FB_VIA_X_COMPATIBILITY bool "X server compatibility" depends on FB_VIA default n help This option reduces the functionality (power saving, ...) of the framebuffer to avoid negative impact on the OpenChrome X server. If you use any X server other than fbdev you should enable this otherwise it should be safe to disable it and allow using all features. endif config FB_NEOMAGIC Loading
drivers/video/via/Makefile +1 −1 Original line number Diff line number Diff line Loading @@ -6,4 +6,4 @@ obj-$(CONFIG_FB_VIA) += viafb.o viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o \ via_utility.o vt1636.o global.o tblDPASetting.o viamode.o \ via-core.o via-gpio.o via_modesetting.o via-core.o via-gpio.o via_modesetting.o via_clock.o
drivers/video/via/hw.c +144 −385 Original line number Diff line number Diff line Loading @@ -22,273 +22,82 @@ #include <linux/via-core.h> #include <asm/olpc.h> #include "global.h" static struct pll_config cle266_pll_config[] = { {19, 4, 0}, {26, 5, 0}, {28, 5, 0}, {31, 5, 0}, {33, 5, 0}, {55, 5, 0}, {102, 5, 0}, {53, 6, 0}, {92, 6, 0}, {98, 6, 0}, {112, 6, 0}, {41, 7, 0}, {60, 7, 0}, {99, 7, 0}, {100, 7, 0}, {83, 8, 0}, {86, 8, 0}, {108, 8, 0}, {87, 9, 0}, {118, 9, 0}, {95, 12, 0}, {115, 12, 0}, {108, 13, 0}, {83, 17, 0}, {67, 20, 0}, {86, 20, 0}, {98, 20, 0}, {121, 24, 0}, {99, 29, 0}, {33, 3, 1}, {15, 4, 1}, {23, 4, 1}, {37, 5, 1}, {83, 5, 1}, {85, 5, 1}, {94, 5, 1}, {103, 5, 1}, {109, 5, 1}, {113, 5, 1}, {121, 5, 1}, {82, 6, 1}, {31, 7, 1}, {55, 7, 1}, {84, 7, 1}, {83, 8, 1}, {76, 9, 1}, {127, 9, 1}, {33, 4, 2}, {75, 4, 2}, {119, 4, 2}, {121, 4, 2}, {91, 5, 2}, {118, 5, 2}, {83, 6, 2}, {109, 6, 2}, {90, 7, 2}, {93, 2, 3}, {53, 3, 3}, {73, 4, 3}, {89, 4, 3}, {105, 4, 3}, {117, 4, 3}, {101, 5, 3}, {121, 5, 3}, {127, 5, 3}, {99, 7, 3} #include "via_clock.h" static struct pll_limit cle266_pll_limits[] = { {19, 19, 4, 0}, {26, 102, 5, 0}, {53, 112, 6, 0}, {41, 100, 7, 0}, {83, 108, 8, 0}, {87, 118, 9, 0}, {95, 115, 12, 0}, {108, 108, 13, 0}, {83, 83, 17, 0}, {67, 98, 20, 0}, {121, 121, 24, 0}, {99, 99, 29, 0}, {33, 33, 3, 1}, {15, 23, 4, 1}, {37, 121, 5, 1}, {82, 82, 6, 1}, {31, 84, 7, 1}, {83, 83, 8, 1}, {76, 127, 9, 1}, {33, 121, 4, 2}, {91, 118, 5, 2}, {83, 109, 6, 2}, {90, 90, 7, 2}, {93, 93, 2, 3}, {53, 53, 3, 3}, {73, 117, 4, 3}, {101, 127, 5, 3}, {99, 99, 7, 3} }; static struct pll_config k800_pll_config[] = { {22, 2, 0}, {28, 3, 0}, {81, 3, 1}, {85, 3, 1}, {98, 3, 1}, {112, 3, 1}, {86, 4, 1}, {166, 4, 1}, {109, 5, 1}, {113, 5, 1}, {121, 5, 1}, {131, 5, 1}, {143, 5, 1}, {153, 5, 1}, {66, 3, 2}, {68, 3, 2}, {95, 3, 2}, {106, 3, 2}, {116, 3, 2}, {93, 4, 2}, {119, 4, 2}, {121, 4, 2}, {133, 4, 2}, {137, 4, 2}, {117, 5, 2}, {118, 5, 2}, {120, 5, 2}, {124, 5, 2}, {132, 5, 2}, {137, 5, 2}, {141, 5, 2}, {166, 5, 2}, {170, 5, 2}, {191, 5, 2}, {206, 5, 2}, {208, 5, 2}, {30, 2, 3}, {69, 3, 3}, {82, 3, 3}, {83, 3, 3}, {109, 3, 3}, {114, 3, 3}, {125, 3, 3}, {89, 4, 3}, {103, 4, 3}, {117, 4, 3}, {126, 4, 3}, {150, 4, 3}, {161, 4, 3}, {121, 5, 3}, {127, 5, 3}, {131, 5, 3}, {134, 5, 3}, {148, 5, 3}, {169, 5, 3}, {172, 5, 3}, {182, 5, 3}, {195, 5, 3}, {196, 5, 3}, {208, 5, 3}, {66, 2, 4}, {85, 3, 4}, {141, 4, 4}, {146, 4, 4}, {161, 4, 4}, {177, 5, 4} static struct pll_limit k800_pll_limits[] = { {22, 22, 2, 0}, {28, 28, 3, 0}, {81, 112, 3, 1}, {86, 166, 4, 1}, {109, 153, 5, 1}, {66, 116, 3, 2}, {93, 137, 4, 2}, {117, 208, 5, 2}, {30, 30, 2, 3}, {69, 125, 3, 3}, {89, 161, 4, 3}, {121, 208, 5, 3}, {66, 66, 2, 4}, {85, 85, 3, 4}, {141, 161, 4, 4}, {177, 177, 5, 4} }; static struct pll_config cx700_pll_config[] = { {98, 3, 1}, {86, 4, 1}, {109, 5, 1}, {110, 5, 1}, {113, 5, 1}, {121, 5, 1}, {131, 5, 1}, {135, 5, 1}, {142, 5, 1}, {143, 5, 1}, {153, 5, 1}, {187, 5, 1}, {208, 5, 1}, {68, 2, 2}, {95, 3, 2}, {116, 3, 2}, {93, 4, 2}, {119, 4, 2}, {133, 4, 2}, {137, 4, 2}, {151, 4, 2}, {166, 4, 2}, {110, 5, 2}, {112, 5, 2}, {117, 5, 2}, {118, 5, 2}, {120, 5, 2}, {132, 5, 2}, {137, 5, 2}, {141, 5, 2}, {151, 5, 2}, {166, 5, 2}, {175, 5, 2}, {191, 5, 2}, {206, 5, 2}, {174, 7, 2}, {82, 3, 3}, {109, 3, 3}, {117, 4, 3}, {150, 4, 3}, {161, 4, 3}, {112, 5, 3}, {115, 5, 3}, {121, 5, 3}, {127, 5, 3}, {129, 5, 3}, {131, 5, 3}, {134, 5, 3}, {138, 5, 3}, {148, 5, 3}, {157, 5, 3}, {169, 5, 3}, {172, 5, 3}, {190, 5, 3}, {195, 5, 3}, {196, 5, 3}, {208, 5, 3}, {141, 5, 4}, {150, 5, 4}, {166, 5, 4}, {176, 5, 4}, {177, 5, 4}, {183, 5, 4}, {202, 5, 4} static struct pll_limit cx700_pll_limits[] = { {98, 98, 3, 1}, {86, 86, 4, 1}, {109, 208, 5, 1}, {68, 68, 2, 2}, {95, 116, 3, 2}, {93, 166, 4, 2}, {110, 206, 5, 2}, {174, 174, 7, 2}, {82, 109, 3, 3}, {117, 161, 4, 3}, {112, 208, 5, 3}, {141, 202, 5, 4} }; static struct pll_config vx855_pll_config[] = { {86, 4, 1}, {108, 5, 1}, {110, 5, 1}, {113, 5, 1}, {121, 5, 1}, {131, 5, 1}, {135, 5, 1}, {142, 5, 1}, {143, 5, 1}, {153, 5, 1}, {164, 5, 1}, {187, 5, 1}, {208, 5, 1}, {110, 5, 2}, {112, 5, 2}, {117, 5, 2}, {118, 5, 2}, {124, 5, 2}, {132, 5, 2}, {137, 5, 2}, {141, 5, 2}, {149, 5, 2}, {151, 5, 2}, {159, 5, 2}, {166, 5, 2}, {167, 5, 2}, {172, 5, 2}, {189, 5, 2}, {191, 5, 2}, {194, 5, 2}, {206, 5, 2}, {208, 5, 2}, {83, 3, 3}, {88, 3, 3}, {109, 3, 3}, {112, 3, 3}, {103, 4, 3}, {105, 4, 3}, {161, 4, 3}, {112, 5, 3}, {115, 5, 3}, {121, 5, 3}, {127, 5, 3}, {134, 5, 3}, {137, 5, 3}, {148, 5, 3}, {157, 5, 3}, {169, 5, 3}, {172, 5, 3}, {182, 5, 3}, {191, 5, 3}, {195, 5, 3}, {209, 5, 3}, {142, 4, 4}, {146, 4, 4}, {161, 4, 4}, {141, 5, 4}, {150, 5, 4}, {165, 5, 4}, {176, 5, 4} static struct pll_limit vx855_pll_limits[] = { {86, 86, 4, 1}, {108, 208, 5, 1}, {110, 208, 5, 2}, {83, 112, 3, 3}, {103, 161, 4, 3}, {112, 209, 5, 3}, {142, 161, 4, 4}, {141, 176, 5, 4} }; /* according to VIA Technologies these values are based on experiment */ Loading Loading @@ -713,6 +522,9 @@ static struct via_device_mapping device_mapping[] = { {VIA_LVDS2, "LVDS2"} }; /* structure with function pointers to support clock control */ static struct via_clock clock; static void load_fix_bit_crtc_reg(void); static void __devinit init_gfx_chip_info(int chip_type); static void __devinit init_tmds_chip_info(void); Loading Loading @@ -1634,69 +1446,54 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active) } static u32 cle266_encode_pll(struct pll_config pll) { return (pll.multiplier << 8) | (pll.rshift << 6) | pll.divisor; } static u32 k800_encode_pll(struct pll_config pll) { return ((pll.divisor - 2) << 16) | (pll.rshift << 10) | (pll.multiplier - 2); } static u32 vx855_encode_pll(struct pll_config pll) { return (pll.divisor << 16) | (pll.rshift << 10) | pll.multiplier; } static inline u32 get_pll_internal_frequency(u32 ref_freq, struct pll_config pll) { return ref_freq / pll.divisor * pll.multiplier; } static inline u32 get_pll_output_frequency(u32 ref_freq, struct pll_config pll) { return get_pll_internal_frequency(ref_freq, pll)>>pll.rshift; } static struct pll_config get_pll_config(struct pll_config *config, int size, static struct via_pll_config get_pll_config(struct pll_limit *limits, int size, int clk) { struct pll_config best = config[0]; struct via_pll_config cur, up, down, best = {0, 1, 0}; const u32 f0 = 14318180; /* X1 frequency */ int i; for (i = 1; i < size; i++) { if (abs(get_pll_output_frequency(f0, config[i]) - clk) < abs(get_pll_output_frequency(f0, best) - clk)) best = config[i]; int i, f; for (i = 0; i < size; i++) { cur.rshift = limits[i].rshift; cur.divisor = limits[i].divisor; cur.multiplier = clk / ((f0 / cur.divisor)>>cur.rshift); f = abs(get_pll_output_frequency(f0, cur) - clk); up = down = cur; up.multiplier++; down.multiplier--; if (abs(get_pll_output_frequency(f0, up) - clk) < f) cur = up; else if (abs(get_pll_output_frequency(f0, down) - clk) < f) cur = down; if (cur.multiplier < limits[i].multiplier_min) cur.multiplier = limits[i].multiplier_min; else if (cur.multiplier > limits[i].multiplier_max) cur.multiplier = limits[i].multiplier_max; f = abs(get_pll_output_frequency(f0, cur) - clk); if (f < abs(get_pll_output_frequency(f0, best) - clk)) best = cur; } return best; } u32 viafb_get_clk_value(int clk) static struct via_pll_config get_best_pll_config(int clk) { u32 value = 0; struct via_pll_config config; switch (viaparinfo->chip_info->gfx_chip_name) { case UNICHROME_CLE266: case UNICHROME_K400: value = cle266_encode_pll(get_pll_config(cle266_pll_config, ARRAY_SIZE(cle266_pll_config), clk)); config = get_pll_config(cle266_pll_limits, ARRAY_SIZE(cle266_pll_limits), clk); break; case UNICHROME_K800: case UNICHROME_PM800: case UNICHROME_CN700: value = k800_encode_pll(get_pll_config(k800_pll_config, ARRAY_SIZE(k800_pll_config), clk)); config = get_pll_config(k800_pll_limits, ARRAY_SIZE(k800_pll_limits), clk); break; case UNICHROME_CX700: case UNICHROME_CN750: Loading @@ -1704,92 +1501,28 @@ u32 viafb_get_clk_value(int clk) case UNICHROME_P4M890: case UNICHROME_P4M900: case UNICHROME_VX800: value = k800_encode_pll(get_pll_config(cx700_pll_config, ARRAY_SIZE(cx700_pll_config), clk)); config = get_pll_config(cx700_pll_limits, ARRAY_SIZE(cx700_pll_limits), clk); break; case UNICHROME_VX855: case UNICHROME_VX900: value = vx855_encode_pll(get_pll_config(vx855_pll_config, ARRAY_SIZE(vx855_pll_config), clk)); config = get_pll_config(vx855_pll_limits, ARRAY_SIZE(vx855_pll_limits), clk); break; } return value; return config; } /* Set VCLK*/ void viafb_set_vclock(u32 clk, int set_iga) { /* H.W. Reset : ON */ viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); if (set_iga == IGA1) { /* Change D,N FOR VCLK */ switch (viaparinfo->chip_info->gfx_chip_name) { case UNICHROME_CLE266: case UNICHROME_K400: via_write_reg(VIASR, SR46, (clk & 0x00FF)); via_write_reg(VIASR, SR47, (clk & 0xFF00) >> 8); break; case UNICHROME_K800: case UNICHROME_PM800: case UNICHROME_CN700: case UNICHROME_CX700: case UNICHROME_CN750: case UNICHROME_K8M890: case UNICHROME_P4M890: case UNICHROME_P4M900: case UNICHROME_VX800: case UNICHROME_VX855: case UNICHROME_VX900: via_write_reg(VIASR, SR44, (clk & 0x0000FF)); via_write_reg(VIASR, SR45, (clk & 0x00FF00) >> 8); via_write_reg(VIASR, SR46, (clk & 0xFF0000) >> 16); break; } } if (set_iga == IGA2) { /* Change D,N FOR LCK */ switch (viaparinfo->chip_info->gfx_chip_name) { case UNICHROME_CLE266: case UNICHROME_K400: via_write_reg(VIASR, SR44, (clk & 0x00FF)); via_write_reg(VIASR, SR45, (clk & 0xFF00) >> 8); break; case UNICHROME_K800: case UNICHROME_PM800: case UNICHROME_CN700: case UNICHROME_CX700: case UNICHROME_CN750: case UNICHROME_K8M890: case UNICHROME_P4M890: case UNICHROME_P4M900: case UNICHROME_VX800: case UNICHROME_VX855: case UNICHROME_VX900: via_write_reg(VIASR, SR4A, (clk & 0x0000FF)); via_write_reg(VIASR, SR4B, (clk & 0x00FF00) >> 8); via_write_reg(VIASR, SR4C, (clk & 0xFF0000) >> 16); break; } } struct via_pll_config config = get_best_pll_config(clk); /* H.W. Reset : OFF */ viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); /* Reset PLL */ if (set_iga == IGA1) { viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1); viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1); } if (set_iga == IGA2) { viafb_write_reg_mask(SR40, VIASR, 0x04, BIT2); viafb_write_reg_mask(SR40, VIASR, 0x00, BIT2); } if (set_iga == IGA1) clock.set_primary_pll(config); if (set_iga == IGA2) clock.set_secondary_pll(config); /* Fire! */ via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */ Loading Loading @@ -2035,7 +1768,7 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, int i; int index = 0; int h_addr, v_addr; u32 pll_D_N, clock, refresh = viafb_refresh; u32 clock, refresh = viafb_refresh; if (viafb_SAMM_ON && set_iga == IGA2) refresh = viafb_refresh1; Loading Loading @@ -2089,14 +1822,13 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, clock = crt_reg.hor_total * crt_reg.ver_total * crt_table[index].refresh_rate; pll_D_N = viafb_get_clk_value(clock); DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N); viafb_set_vclock(pll_D_N, set_iga); viafb_set_vclock(clock, set_iga); } void __devinit viafb_init_chip_info(int chip_type) { via_clock_init(&clock, chip_type); init_gfx_chip_info(chip_type); init_tmds_chip_info(); init_lvds_chip_info(); Loading Loading @@ -2584,6 +2316,33 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, get_sync(viafbinfo1)); } clock.set_engine_pll_state(VIA_STATE_ON); clock.set_primary_clock_source(VIA_CLKSRC_X1, true); clock.set_secondary_clock_source(VIA_CLKSRC_X1, true); #ifdef CONFIG_FB_VIA_X_COMPATIBILITY clock.set_primary_pll_state(VIA_STATE_ON); clock.set_primary_clock_state(VIA_STATE_ON); clock.set_secondary_pll_state(VIA_STATE_ON); clock.set_secondary_clock_state(VIA_STATE_ON); #else if (viaparinfo->shared->iga1_devices) { clock.set_primary_pll_state(VIA_STATE_ON); clock.set_primary_clock_state(VIA_STATE_ON); } else { clock.set_primary_pll_state(VIA_STATE_OFF); clock.set_primary_clock_state(VIA_STATE_OFF); } if (viaparinfo->shared->iga2_devices) { clock.set_secondary_pll_state(VIA_STATE_ON); clock.set_secondary_clock_state(VIA_STATE_ON); } else { clock.set_secondary_pll_state(VIA_STATE_OFF); clock.set_secondary_clock_state(VIA_STATE_OFF); } #endif /*CONFIG_FB_VIA_X_COMPATIBILITY*/ via_set_state(devices, VIA_STATE_ON); device_screen_on(); return 1; Loading
drivers/video/via/hw.h +3 −11 Original line number Diff line number Diff line Loading @@ -732,20 +732,13 @@ struct _lcd_scaling_factor { struct _lcd_ver_scaling_factor lcd_ver_scaling_factor; }; struct pll_config { u16 multiplier; struct pll_limit { u16 multiplier_min; u16 multiplier_max; u8 divisor; u8 rshift; }; struct pll_map { u32 clk; struct pll_config cle266_pll; struct pll_config k800_pll; struct pll_config cx700_pll; struct pll_config vx855_pll; }; struct rgbLUT { u8 red; u8 green; Loading Loading @@ -935,7 +928,6 @@ void viafb_lock_crt(void); void viafb_unlock_crt(void); void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga); void viafb_write_regx(struct io_reg RegTable[], int ItemNum); u32 viafb_get_clk_value(int clk); void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active); void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ *p_gfx_dpa_setting); Loading
drivers/video/via/lcd.c +2 −5 Original line number Diff line number Diff line Loading @@ -558,7 +558,7 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, int set_vres = plvds_setting_info->v_active; int panel_hres = plvds_setting_info->lcd_panel_hres; int panel_vres = plvds_setting_info->lcd_panel_vres; u32 pll_D_N, clock; u32 clock; struct display_timing mode_crt_reg, panel_crt_reg; struct crt_mode_table *panel_crt_table = NULL; struct VideoModeTable *vmode_tbl = viafb_get_mode(panel_hres, Loading Loading @@ -609,10 +609,7 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, viafb_load_FIFO_reg(set_iga, set_hres, set_vres); fill_lcd_format(); pll_D_N = viafb_get_clk_value(clock); DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N); viafb_set_vclock(pll_D_N, set_iga); viafb_set_vclock(clock, set_iga); lcd_patch_skew(plvds_setting_info, plvds_chip_info); /* If K8M800, enable LCD Prefetch Mode. */ Loading