uboot/arch/powerpc/cpu/mpc5xx/serial.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2003
   3 * Martin Winistoerfer, martinwinistoerfer@gmx.ch.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8/*
   9 * File:                serial.c
  10 *
  11 * Discription:         Serial interface driver for SCI1 and SCI2.
  12 *                      Since this code will be called from ROM use
  13 *                      only non-static local variables.
  14 *
  15 */
  16
  17#include <common.h>
  18#include <watchdog.h>
  19#include <command.h>
  20#include <mpc5xx.h>
  21#include <serial.h>
  22#include <linux/compiler.h>
  23
  24DECLARE_GLOBAL_DATA_PTR;
  25
  26/*
  27 * Local functions
  28 */
  29
  30static int ready_to_send(void)
  31{
  32        volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
  33        volatile short status;
  34
  35        do {
  36#if defined(CONFIG_5xx_CONS_SCI1)
  37                status = immr->im_qsmcm.qsmcm_sc1sr;
  38#else
  39                status = immr->im_qsmcm.qsmcm_sc2sr;
  40#endif
  41
  42#if defined(CONFIG_WATCHDOG)
  43                reset_5xx_watchdog (immr);
  44#endif
  45        } while ((status & SCI_TDRE) == 0);
  46        return 1;
  47
  48}
  49
  50/*
  51 * Minimal global serial functions needed to use one of the SCI modules.
  52 */
  53
  54static int mpc5xx_serial_init(void)
  55{
  56        volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
  57
  58        serial_setbrg();
  59
  60#if defined(CONFIG_5xx_CONS_SCI1)
  61        /* 10-Bit, 1 start bit, 8 data bit, no parity, 1 stop bit */
  62        immr->im_qsmcm.qsmcm_scc1r1 = SCI_M_10;
  63        immr->im_qsmcm.qsmcm_scc1r1 = SCI_TE | SCI_RE;
  64#else
  65        immr->im_qsmcm.qsmcm_scc2r1 = SCI_M_10;
  66        immr->im_qsmcm.qsmcm_scc2r1 = SCI_TE | SCI_RE;
  67#endif
  68        return 0;
  69}
  70
  71static void mpc5xx_serial_putc(const char c)
  72{
  73        volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
  74
  75        /* Test for completition */
  76        if(ready_to_send()) {
  77#if defined(CONFIG_5xx_CONS_SCI1)
  78                immr->im_qsmcm.qsmcm_sc1dr = (short)c;
  79#else
  80                immr->im_qsmcm.qsmcm_sc2dr = (short)c;
  81#endif
  82                if(c == '\n') {
  83                        if(ready_to_send());
  84#if defined(CONFIG_5xx_CONS_SCI1)
  85                        immr->im_qsmcm.qsmcm_sc1dr = (short)'\r';
  86#else
  87                        immr->im_qsmcm.qsmcm_sc2dr = (short)'\r';
  88#endif
  89                }
  90        }
  91}
  92
  93static int mpc5xx_serial_getc(void)
  94{
  95        volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
  96        volatile short status;
  97        unsigned char tmp;
  98
  99        /* New data ? */
 100        do {
 101#if defined(CONFIG_5xx_CONS_SCI1)
 102                status = immr->im_qsmcm.qsmcm_sc1sr;
 103#else
 104                status = immr->im_qsmcm.qsmcm_sc2sr;
 105#endif
 106
 107#if defined(CONFIG_WATCHDOG)
 108                reset_5xx_watchdog (immr);
 109#endif
 110        } while ((status & SCI_RDRF) == 0);
 111
 112        /* Read data */
 113#if defined(CONFIG_5xx_CONS_SCI1)
 114        tmp = (unsigned char)(immr->im_qsmcm.qsmcm_sc1dr & SCI_SCXDR_MK);
 115#else
 116        tmp = (unsigned char)( immr->im_qsmcm.qsmcm_sc2dr & SCI_SCXDR_MK);
 117#endif
 118        return  tmp;
 119}
 120
 121static int mpc5xx_serial_tstc(void)
 122{
 123        volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
 124        short status;
 125
 126        /* New data character ? */
 127#if defined(CONFIG_5xx_CONS_SCI1)
 128        status = immr->im_qsmcm.qsmcm_sc1sr;
 129#else
 130        status = immr->im_qsmcm.qsmcm_sc2sr;
 131#endif
 132        return (status & SCI_RDRF);
 133}
 134
 135static void mpc5xx_serial_setbrg(void)
 136{
 137        volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
 138        short scxbr;
 139
 140        /* Set baudrate */
 141        scxbr = (gd->cpu_clk / (32 * gd->baudrate));
 142#if defined(CONFIG_5xx_CONS_SCI1)
 143        immr->im_qsmcm.qsmcm_scc1r0 = (scxbr & SCI_SCXBR_MK);
 144#else
 145        immr->im_qsmcm.qsmcm_scc2r0 = (scxbr & SCI_SCXBR_MK);
 146#endif
 147}
 148
 149static struct serial_device mpc5xx_serial_drv = {
 150        .name   = "mpc5xx_serial",
 151        .start  = mpc5xx_serial_init,
 152        .stop   = NULL,
 153        .setbrg = mpc5xx_serial_setbrg,
 154        .putc   = mpc5xx_serial_putc,
 155        .puts   = default_serial_puts,
 156        .getc   = mpc5xx_serial_getc,
 157        .tstc   = mpc5xx_serial_tstc,
 158};
 159
 160void mpc5xx_serial_initialize(void)
 161{
 162        serial_register(&mpc5xx_serial_drv);
 163}
 164
 165__weak struct serial_device *default_serial_console(void)
 166{
 167        return &mpc5xx_serial_drv;
 168}
 169