Changeset 3610


Ignore:
Timestamp:
Sep 26, 2008 9:15:38 PM (5 years ago)
Author:
mjones
Message:

This patch fixes the dbm690t keyboard not working issue. It should also
fix the a8n_e and any other it8712f SIO keyboard issues. The it8712f
requires an archaic PS/2 mode setting to the keyboard controller before
accessing the keyboard. Beyond that, I made the keyboard controller and
keyboard init more robust and added more informative debug output.

Signed-off-by: Marc Jones <marc.jones@…>
Acked-by: Stefan Reinauer <stepan@…>

Location:
trunk/coreboot-v2/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/coreboot-v2/src/pc80/keyboard.c

    r2869 r3610  
     1/* 
     2 * This file is part of the coreboot project. 
     3 * 
     4 * Copyright (C) 2008 Advanced Micro Devices, Inc. 
     5 * Copyright (C) ???? Ollie Lo <ollielo@hotmail.com> 
     6 * 
     7 * This program is free software; you can redistribute it and/or modify 
     8 * it under the terms of the GNU General Public License as published by 
     9 * the Free Software Foundation; version 2 of the License. 
     10 * 
     11 * This program is distributed in the hope that it will be useful, 
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     14 * GNU General Public License for more details. 
     15 * 
     16 * You should have received a copy of the GNU General Public License 
     17 * along with this program; if not, write to the Free Software 
     18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA 
     19 */ 
     20 
     21 
    122#include <console/console.h> 
    223#include <pc80/keyboard.h> 
     
    425#include <arch/io.h> 
    526 
    6 static int kbd_empty_input_buffer(void) 
    7 { 
    8         unsigned long timeout; 
     27static int kbc_input_buffer_empty(void) 
     28{ 
     29        u32 timeout; 
    930        for(timeout = 1000000; timeout && (inb(0x64) & 0x02); timeout--) { 
    10                 post_code(0); 
     31                inb(0x80); 
     32        } 
     33 
     34        if (!timeout) { 
     35                printk_err("Unexpected Keyboard controller input buffer full\n"); 
    1136        } 
    1237        return !!timeout; 
    1338} 
    1439 
    15 static int kbd_empty_output_buffer(void) 
    16 { 
    17         unsigned long timeout; 
     40 
     41static int kbc_output_buffer_full(void) 
     42{ 
     43        u32 timeout; 
    1844        for(timeout = 1000000; timeout && ((inb(0x64) & 0x01) == 0); timeout--) { 
    19                 post_code(0); 
     45                inb(0x80); 
     46        } 
     47 
     48        if (!timeout) { 
     49                printk_err("Keyboard controller output buffer result timeout\n"); 
    2050        } 
    2151        return !!timeout; 
    2252} 
    2353 
    24 /* much better keyboard init courtesy ollie@sis.com.tw  
    25    TODO: Typematic Setting, the keyboard is too slow for me */ 
     54 
     55static int kbc_cleanup_buffers(void) 
     56{ 
     57        u32 timeout; 
     58        for(timeout = 1000000; timeout && (inb(0x64) & 0x03); timeout--) { 
     59                inb(0x60); 
     60        } 
     61 
     62        if (!timeout) { 
     63                printk_err("Couldn't cleanup the keyboard controller buffers\n"); 
     64                printk_err("0x64: 0x%x, 0x60: 0x%x\n", inb(0x64), inb(0x60)); 
     65        } 
     66        return !!timeout; 
     67} 
     68 
     69 
     70static u8 send_keyboard(u8 command) 
     71{ 
     72        u8 regval = 0; 
     73        u8 resend = 10; 
     74 
     75        do { 
     76                if (!kbc_input_buffer_empty()) return 0; 
     77                outb(command, 0x60); 
     78                if (!kbc_output_buffer_full()) return 0; 
     79                regval = inb(0x60); 
     80                --resend; 
     81        } while (regval == 0xFE && resend > 0); 
     82 
     83        return regval; 
     84} 
     85 
     86 
    2687static void pc_keyboard_init(struct pc_keyboard *keyboard) 
    2788{ 
    28         unsigned char regval; 
    29  
     89        u8 regval; 
     90        u8 resend; 
    3091        printk_debug("Keyboard init...\n"); 
    31         /* send cmd = 0xAA, self test 8042 */ 
    32         outb(0xaa, 0x64); 
    33  
    34         /* empty input buffer or any other command/data will be lost */ 
    35         if (!kbd_empty_input_buffer()) { 
    36                 printk_err("Keyboard input buffer would not empty\n"); 
    37                 return; 
    38         } 
    39  
    40         /* empty output buffer or any other command/data will be lost */ 
    41         if (!kbd_empty_output_buffer()) { 
    42                 printk_err("Keyboard output buffer would not empty\n"); 
    43                 return; 
    44         } 
    45  
    46         /* read self-test result, 0x55 should be returned form 0x60 */ 
     92 
     93        /* clean up any junk that might have been in the kbc */ 
     94        if (!kbc_cleanup_buffers()) return; 
     95 
     96        /* reset/self test 8042 - send cmd 0xAA,  */ 
     97        if (!kbc_input_buffer_empty()) return; 
     98        outb(0xAA, 0x64); 
     99        if (!kbc_output_buffer_full()) return; 
     100 
     101        /* read self-test result, 0x55 is returned in the output buffer (0x60) */ 
    47102        if ((regval = inb(0x60) != 0x55)) { 
    48                 printk_err("Keyboard selftest failed\n"); 
    49                 return; 
    50         } 
    51  
    52         /* enable keyboard interface */ 
    53         outb(0x60, 0x64); 
    54         kbd_empty_input_buffer(); 
    55  
    56         /* send cmd: enable IRQ 1 */ 
    57         outb(0x61, 0x60); 
    58         kbd_empty_input_buffer(); 
    59  
    60         /* reset kerboard and self test  (keyboard side) */ 
    61         outb(0xff, 0x60); 
    62  
    63         /* empty inut bufferm or any other command/data will be lost */ 
    64         kbd_empty_input_buffer(); 
    65  
    66         /* empty output buffer or any other command/data will be lost */ 
    67         kbd_empty_output_buffer(); 
    68  
    69         if ((regval = inb(0x60) != 0xfa)) 
    70                 return; 
    71  
    72         kbd_empty_output_buffer(); 
    73         if ((regval = inb(0x60) != 0xaa)) 
    74                 return; 
    75 } 
     103                printk_err("Keyboard Controller selftest failed: 0x%x\n", regval); 
     104                return; 
     105        } 
     106 
     107        /* Enable keyboard interface - No IRQ*/ 
     108        resend = 10; 
     109        regval = 0; 
     110        do { 
     111                if (!kbc_input_buffer_empty()) return; 
     112                outb(0x60, 0x64); 
     113                if (!kbc_input_buffer_empty()) return; 
     114                outb(0x20, 0x60);       /* send cmd: enable keyboard and IRQ 1 */ 
     115                u8 resend = 10; 
     116                if ((inb(0x64) & 0x01)) { 
     117                        regval = inb(0x60); 
     118                } 
     119                --resend; 
     120        } while (regval == 0xFE && resend > 0); 
     121 
     122        /* clean up any junk that might have been in the keyboard */ 
     123        if (!kbc_cleanup_buffers()) return; 
     124 
     125        /* reset keyboard and self test (keyboard side) */ 
     126        regval = send_keyboard(0xFF); 
     127        if (regval != 0xFA) { 
     128                printk_err("Keyboard selftest failed ACK: 0x%x\n", regval); 
     129                return; 
     130        } 
     131        if (!kbc_output_buffer_full()) return; 
     132        regval = inb(0x60); 
     133        if (regval != 0xAA) { 
     134                printk_err("Keyboard selftest failed: 0x%x\n", regval); 
     135                return; 
     136        } 
     137 
     138        /* 
     139         * The following set scancode stuff is what normal BIOS do. It could be 
     140         * argued that coreboot shouldn't set the scan code..... 
     141         */ 
     142 
     143        /* disable the keyboard */ 
     144        regval = send_keyboard(0xF5); 
     145        if (regval != 0xFA) { 
     146                printk_err("Keyboard disable failed ACK: 0x%x\n", regval); 
     147                return; 
     148        } 
     149 
     150        /* Set scancode command */ 
     151        regval = send_keyboard(0xF0); 
     152        if (regval != 0xFA) { 
     153                printk_err("Keyboard set scancode cmd failed ACK: 0x%x\n", regval); 
     154                return; 
     155        } 
     156        /* Set scancode mode 2 */ 
     157        regval = send_keyboard(0x02); 
     158        if (regval != 0xFA) { 
     159                printk_err("Keyboard set scancode mode failed ACK: 0x%x\n", regval); 
     160                return; 
     161        } 
     162 
     163        /* enable the keyboard */ 
     164        regval = send_keyboard(0xF4); 
     165        if (regval != 0xFA) { 
     166                printk_err("Keyboard enable failed ACK: 0x%x\n", regval); 
     167                return; 
     168        } 
     169 
     170        /* All is well - enable keyboard interface */ 
     171        resend = 10; 
     172        regval = 0; 
     173        do { 
     174                if (!kbc_input_buffer_empty()) return; 
     175                outb(0x60, 0x64); 
     176                if (!kbc_input_buffer_empty()) return; 
     177                outb(0x61, 0x60);       /* send cmd: enable keyboard and IRQ 1 */ 
     178                if ((inb(0x64) & 0x01)) { 
     179                        regval = inb(0x60); 
     180                } 
     181                --resend; 
     182        } while (regval == 0xFE && resend > 0); 
     183} 
     184 
    76185 
    77186void init_pc_keyboard(unsigned port0, unsigned port1, struct pc_keyboard *kbd) 
     
    81190        } 
    82191} 
     192 
     193/* 
     194 * Support PS/2 mode -  oddball SIOs(KBC) need this setup 
     195 * Not well documented. Google - 0xcb keyboard controller 
     196 * This is called before pc_keyboard_init(). 
     197 */ 
     198void set_kbc_ps2_mode() 
     199{ 
     200        /* clean up any junk that might have been in the kbc */ 
     201        if (!kbc_cleanup_buffers()) return; 
     202 
     203        /* reset/self test 8042 before we can do anything */ 
     204        if (!kbc_input_buffer_empty()) return; 
     205        outb(0xAA, 0x64); 
     206        if (!kbc_output_buffer_full()) return; 
     207 
     208        /* read self-test result, 0x55 is returned in the output buffer (0x60) */ 
     209        if ((inb(0x60) != 0x55)) { 
     210                printk_err("Keyboard Controller selftest failed\n"); 
     211                return; 
     212        } 
     213 
     214        /* Support PS/2 mode */ 
     215        if (!kbc_input_buffer_empty()) return; 
     216        outb(0xcb, 0x64); 
     217        if (!kbc_input_buffer_empty()) return; 
     218        outb(0x01, 0x60); 
     219        kbc_cleanup_buffers(); 
     220} 
  • trunk/coreboot-v2/src/superio/ite/it8712f/superio.c

    r3052 r3610  
    7777                res0 = find_resource(dev, PNP_IDX_IO0); 
    7878                res1 = find_resource(dev, PNP_IDX_IO1); 
     79                set_kbc_ps2_mode(); 
    7980                init_pc_keyboard(res0->base, res1->base, &conf->keyboard); 
    8081                break; 
Note: See TracChangeset for help on using the changeset viewer.