1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * MPC5200 PSC serial console support. 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Author: Grant Likely <grant.likely@secretlab.ca> 6*4882a593Smuzhiyun * 7*4882a593Smuzhiyun * Copyright (c) 2007 Secret Lab Technologies Ltd. 8*4882a593Smuzhiyun * Copyright (c) 2007 Freescale Semiconductor, Inc. 9*4882a593Smuzhiyun * 10*4882a593Smuzhiyun * It is assumed that the firmware (or the platform file) has already set 11*4882a593Smuzhiyun * up the port. 12*4882a593Smuzhiyun */ 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun #include "types.h" 15*4882a593Smuzhiyun #include "io.h" 16*4882a593Smuzhiyun #include "ops.h" 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun /* Programmable Serial Controller (PSC) status register bits */ 19*4882a593Smuzhiyun #define MPC52xx_PSC_SR 0x04 20*4882a593Smuzhiyun #define MPC52xx_PSC_SR_RXRDY 0x0100 21*4882a593Smuzhiyun #define MPC52xx_PSC_SR_RXFULL 0x0200 22*4882a593Smuzhiyun #define MPC52xx_PSC_SR_TXRDY 0x0400 23*4882a593Smuzhiyun #define MPC52xx_PSC_SR_TXEMP 0x0800 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun #define MPC52xx_PSC_BUFFER 0x0C 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun static void *psc; 28*4882a593Smuzhiyun psc_open(void)29*4882a593Smuzhiyunstatic int psc_open(void) 30*4882a593Smuzhiyun { 31*4882a593Smuzhiyun /* Assume the firmware has already configured the PSC into 32*4882a593Smuzhiyun * uart mode */ 33*4882a593Smuzhiyun return 0; 34*4882a593Smuzhiyun } 35*4882a593Smuzhiyun psc_putc(unsigned char c)36*4882a593Smuzhiyunstatic void psc_putc(unsigned char c) 37*4882a593Smuzhiyun { 38*4882a593Smuzhiyun while (!(in_be16(psc + MPC52xx_PSC_SR) & MPC52xx_PSC_SR_TXRDY)) ; 39*4882a593Smuzhiyun out_8(psc + MPC52xx_PSC_BUFFER, c); 40*4882a593Smuzhiyun } 41*4882a593Smuzhiyun psc_tstc(void)42*4882a593Smuzhiyunstatic unsigned char psc_tstc(void) 43*4882a593Smuzhiyun { 44*4882a593Smuzhiyun return (in_be16(psc + MPC52xx_PSC_SR) & MPC52xx_PSC_SR_RXRDY) != 0; 45*4882a593Smuzhiyun } 46*4882a593Smuzhiyun psc_getc(void)47*4882a593Smuzhiyunstatic unsigned char psc_getc(void) 48*4882a593Smuzhiyun { 49*4882a593Smuzhiyun while (!(in_be16(psc + MPC52xx_PSC_SR) & MPC52xx_PSC_SR_RXRDY)) ; 50*4882a593Smuzhiyun return in_8(psc + MPC52xx_PSC_BUFFER); 51*4882a593Smuzhiyun } 52*4882a593Smuzhiyun mpc5200_psc_console_init(void * devp,struct serial_console_data * scdp)53*4882a593Smuzhiyunint mpc5200_psc_console_init(void *devp, struct serial_console_data *scdp) 54*4882a593Smuzhiyun { 55*4882a593Smuzhiyun /* Get the base address of the psc registers */ 56*4882a593Smuzhiyun if (dt_get_virtual_reg(devp, &psc, 1) < 1) 57*4882a593Smuzhiyun return -1; 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun scdp->open = psc_open; 60*4882a593Smuzhiyun scdp->putc = psc_putc; 61*4882a593Smuzhiyun scdp->getc = psc_getc; 62*4882a593Smuzhiyun scdp->tstc = psc_tstc; 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun return 0; 65*4882a593Smuzhiyun } 66