uboot/board/rbc823/kbd.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2000
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24/* Modified by Udi Finkelstein
  25 *
  26 * This file includes communication routines for SMC1 that can run even if
  27 * SMC2 have already been initialized.
  28 */
  29
  30#include <common.h>
  31#include <watchdog.h>
  32#include <commproc.h>
  33#include <stdio_dev.h>
  34#include <lcd.h>
  35
  36DECLARE_GLOBAL_DATA_PTR;
  37
  38#define SMC_INDEX       0
  39#define PROFF_SMC       PROFF_SMC1
  40#define CPM_CR_CH_SMC   CPM_CR_CH_SMC1
  41
  42#define RBC823_KBD_BAUDRATE     38400
  43#define CPM_KEYBOARD_BASE       0x1000
  44/*
  45 * Minimal serial functions needed to use one of the SMC ports
  46 * as serial console interface.
  47 */
  48
  49void smc1_setbrg (void)
  50{
  51        volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
  52        volatile cpm8xx_t *cp = &(im->im_cpm);
  53
  54        /* Set up the baud rate generator.
  55         * See 8xx_io/commproc.c for details.
  56         *
  57         * Wire BRG2 to SMC1, BRG1 to SMC2
  58         */
  59
  60        cp->cp_simode = 0x00001000;
  61
  62        cp->cp_brgc2 =
  63                (((gd->cpu_clk / 16 / RBC823_KBD_BAUDRATE)-1) << 1) | CPM_BRG_EN;
  64}
  65
  66int smc1_init (void)
  67{
  68        volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
  69        volatile smc_t *sp;
  70        volatile smc_uart_t *up;
  71        volatile cbd_t *tbdf, *rbdf;
  72        volatile cpm8xx_t *cp = &(im->im_cpm);
  73        uint    dpaddr;
  74
  75        /* initialize pointers to SMC */
  76
  77        sp = (smc_t *) &(cp->cp_smc[SMC_INDEX]);
  78        up = (smc_uart_t *) &cp->cp_dparam[PROFF_SMC];
  79
  80        /* Disable transmitter/receiver.
  81        */
  82        sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
  83
  84        /* Enable SDMA.
  85        */
  86        im->im_siu_conf.sc_sdcr = 1;
  87
  88        /* clear error conditions */
  89#ifdef  CONFIG_SYS_SDSR
  90        im->im_sdma.sdma_sdsr = CONFIG_SYS_SDSR;
  91#else
  92        im->im_sdma.sdma_sdsr = 0x83;
  93#endif
  94
  95        /* clear SDMA interrupt mask */
  96#ifdef  CONFIG_SYS_SDMR
  97        im->im_sdma.sdma_sdmr = CONFIG_SYS_SDMR;
  98#else
  99        im->im_sdma.sdma_sdmr = 0x00;
 100#endif
 101
 102        /* Use Port B for SMC1 instead of other functions.
 103        */
 104        cp->cp_pbpar |=  0x000000c0;
 105        cp->cp_pbdir &= ~0x000000c0;
 106        cp->cp_pbodr &= ~0x000000c0;
 107
 108        /* Set the physical address of the host memory buffers in
 109         * the buffer descriptors.
 110         */
 111
 112#ifdef CONFIG_SYS_ALLOC_DPRAM
 113        dpaddr = dpram_alloc_align (sizeof(cbd_t)*2 + 2, 8) ;
 114#else
 115        dpaddr = CPM_KEYBOARD_BASE ;
 116#endif
 117
 118        /* Allocate space for two buffer descriptors in the DP ram.
 119         * For now, this address seems OK, but it may have to
 120         * change with newer versions of the firmware.
 121         * damm: allocating space after the two buffers for rx/tx data
 122         */
 123
 124        rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];
 125        rbdf->cbd_bufaddr = (uint) (rbdf+2);
 126        rbdf->cbd_sc = 0;
 127        tbdf = rbdf + 1;
 128        tbdf->cbd_bufaddr = ((uint) (rbdf+2)) + 1;
 129        tbdf->cbd_sc = 0;
 130
 131        /* Set up the uart parameters in the parameter ram.
 132        */
 133        up->smc_rbase = dpaddr;
 134        up->smc_tbase = dpaddr+sizeof(cbd_t);
 135        up->smc_rfcr = SMC_EB;
 136        up->smc_tfcr = SMC_EB;
 137
 138        /* Set UART mode, 8 bit, no parity, one stop.
 139         * Enable receive and transmit.
 140         */
 141        sp->smc_smcmr = smcr_mk_clen(9) |  SMCMR_SM_UART;
 142
 143        /* Mask all interrupts and remove anything pending.
 144        */
 145        sp->smc_smcm = 0;
 146        sp->smc_smce = 0xff;
 147
 148        /* Set up the baud rate generator.
 149        */
 150        smc1_setbrg ();
 151
 152        /* Make the first buffer the only buffer.
 153        */
 154        tbdf->cbd_sc |= BD_SC_WRAP;
 155        rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
 156
 157        /* Single character receive.
 158        */
 159        up->smc_mrblr = 1;
 160        up->smc_maxidl = 0;
 161
 162        /* Initialize Tx/Rx parameters.
 163        */
 164
 165        while (cp->cp_cpcr & CPM_CR_FLG)  /* wait if cp is busy */
 166          ;
 167
 168        cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC, CPM_CR_INIT_TRX) | CPM_CR_FLG;
 169
 170        while (cp->cp_cpcr & CPM_CR_FLG)  /* wait if cp is busy */
 171          ;
 172
 173        /* Enable transmitter/receiver.
 174        */
 175        sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
 176
 177        return (0);
 178}
 179
 180void smc1_putc(const char c)
 181{
 182        volatile cbd_t          *tbdf;
 183        volatile char           *buf;
 184        volatile smc_uart_t     *up;
 185        volatile immap_t        *im = (immap_t *)CONFIG_SYS_IMMR;
 186        volatile cpm8xx_t       *cpmp = &(im->im_cpm);
 187
 188        up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
 189
 190        tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
 191
 192        /* Wait for last character to go.
 193        */
 194
 195        buf = (char *)tbdf->cbd_bufaddr;
 196
 197        *buf = c;
 198        tbdf->cbd_datlen = 1;
 199        tbdf->cbd_sc |= BD_SC_READY;
 200        __asm__("eieio");
 201
 202        while (tbdf->cbd_sc & BD_SC_READY) {
 203                WATCHDOG_RESET ();
 204                __asm__("eieio");
 205        }
 206}
 207
 208int smc1_getc(void)
 209{
 210        volatile cbd_t          *rbdf;
 211        volatile unsigned char  *buf;
 212        volatile smc_uart_t     *up;
 213        volatile immap_t        *im = (immap_t *)CONFIG_SYS_IMMR;
 214        volatile cpm8xx_t       *cpmp = &(im->im_cpm);
 215        unsigned char           c;
 216
 217        up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
 218
 219        rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
 220
 221        /* Wait for character to show up.
 222        */
 223        buf = (unsigned char *)rbdf->cbd_bufaddr;
 224
 225        while (rbdf->cbd_sc & BD_SC_EMPTY)
 226                WATCHDOG_RESET ();
 227
 228        c = *buf;
 229        rbdf->cbd_sc |= BD_SC_EMPTY;
 230
 231        return(c);
 232}
 233
 234int smc1_tstc(void)
 235{
 236        volatile cbd_t          *rbdf;
 237        volatile smc_uart_t     *up;
 238        volatile immap_t        *im = (immap_t *)CONFIG_SYS_IMMR;
 239        volatile cpm8xx_t       *cpmp = &(im->im_cpm);
 240
 241        up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC];
 242
 243        rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
 244
 245        return(!(rbdf->cbd_sc & BD_SC_EMPTY));
 246}
 247
 248/* search for keyboard and register it if found */
 249int drv_keyboard_init(void)
 250{
 251        int error = 0;
 252        struct stdio_dev kbd_dev;
 253
 254        if (0) {
 255                /* register the keyboard */
 256                memset (&kbd_dev, 0, sizeof(struct stdio_dev));
 257                strcpy(kbd_dev.name, "kbd");
 258                kbd_dev.flags =  DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
 259                kbd_dev.putc = NULL;
 260                kbd_dev.puts = NULL;
 261                kbd_dev.getc = smc1_getc;
 262                kbd_dev.tstc = smc1_tstc;
 263                error = stdio_register (&kbd_dev);
 264        } else {
 265                lcd_is_enabled = 0;
 266                lcd_disable();
 267        }
 268        return error;
 269}
 270