linux/drivers/tty/serial/ucc_uart.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Freescale QUICC Engine UART device driver
 *
 * Author: Timur Tabi <[email protected]>
 *
 * Copyright 2007 Freescale Semiconductor, Inc.
 *
 * This driver adds support for UART devices via Freescale's QUICC Engine
 * found on some Freescale SOCs.
 *
 * If Soft-UART support is needed but not already present, then this driver
 * will request and upload the "Soft-UART" microcode upon probe.  The
 * filename of the microcode should be fsl_qe_ucode_uart_X_YZ.bin, where "X"
 * is the name of the SOC (e.g. 8323), and YZ is the revision of the SOC,
 * (e.g. "11" for 1.1).
 */

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/dma-mapping.h>

#include <soc/fsl/qe/ucc_slow.h>

#include <linux/firmware.h>
#include <soc/fsl/cpm.h>

#ifdef CONFIG_PPC32
#include <asm/reg.h> /* mfspr, SPRN_SVR */
#endif

/*
 * The GUMR flag for Soft UART.  This would normally be defined in qe.h,
 * but Soft-UART is a hack and we want to keep everything related to it in
 * this file.
 */
#define UCC_SLOW_GUMR_H_SUART

/*
 * soft_uart is 1 if we need to use Soft-UART mode
 */
static int soft_uart;
/*
 * firmware_loaded is 1 if the firmware has been loaded, 0 otherwise.
 */
static int firmware_loaded;

/* Enable this macro to configure all serial ports in internal loopback
   mode */
/* #define LOOPBACK */

/* The major and minor device numbers are defined in
 * Documentation/admin-guide/devices.txt.  For the QE
 * UART, we have major number 204 and minor numbers 46 - 49, which are the
 * same as for the CPM2.  This decision was made because no Freescale part
 * has both a CPM and a QE.
 */
#define SERIAL_QE_MAJOR
#define SERIAL_QE_MINOR

/* Since we only have minor numbers 46 - 49, there is a hard limit of 4 ports */
#define UCC_MAX_UART

/* The number of buffer descriptors for receiving characters. */
#define RX_NUM_FIFO

/* The number of buffer descriptors for transmitting characters. */
#define TX_NUM_FIFO

/* The maximum size of the character buffer for a single RX BD. */
#define RX_BUF_SIZE

/* The maximum size of the character buffer for a single TX BD. */
#define TX_BUF_SIZE

/*
 * The number of jiffies to wait after receiving a close command before the
 * device is actually closed.  This allows the last few characters to be
 * sent over the wire.
 */
#define UCC_WAIT_CLOSING

struct ucc_uart_pram {} __attribute__ ((packed));

/* SUPSMR definitions, for Soft-UART only */
#define UCC_UART_SUPSMR_SL
#define UCC_UART_SUPSMR_RPM_MASK
#define UCC_UART_SUPSMR_RPM_ODD
#define UCC_UART_SUPSMR_RPM_LOW
#define UCC_UART_SUPSMR_RPM_EVEN
#define UCC_UART_SUPSMR_RPM_HIGH
#define UCC_UART_SUPSMR_PEN
#define UCC_UART_SUPSMR_TPM_MASK
#define UCC_UART_SUPSMR_TPM_ODD
#define UCC_UART_SUPSMR_TPM_LOW
#define UCC_UART_SUPSMR_TPM_EVEN
#define UCC_UART_SUPSMR_TPM_HIGH
#define UCC_UART_SUPSMR_FRZ
#define UCC_UART_SUPSMR_UM_MASK
#define UCC_UART_SUPSMR_UM_NORMAL
#define UCC_UART_SUPSMR_UM_MAN_MULTI
#define UCC_UART_SUPSMR_UM_AUTO_MULTI
#define UCC_UART_SUPSMR_CL_MASK
#define UCC_UART_SUPSMR_CL_8
#define UCC_UART_SUPSMR_CL_7
#define UCC_UART_SUPSMR_CL_6
#define UCC_UART_SUPSMR_CL_5

#define UCC_UART_TX_STATE_AHDLC
#define UCC_UART_TX_STATE_UART
#define UCC_UART_TX_STATE_X1
#define UCC_UART_TX_STATE_X16

#define UCC_UART_PRAM_ALIGNMENT

#define UCC_UART_SIZE_OF_BD
#define NUM_CONTROL_CHARS

/* Private per-port data structure */
struct uart_qe_port {};

static struct uart_driver ucc_uart_driver =;

/*
 * Virtual to physical address translation.
 *
 * Given the virtual address for a character buffer, this function returns
 * the physical (DMA) equivalent.
 */
static inline dma_addr_t cpu2qe_addr(void *addr, struct uart_qe_port *qe_port)
{}

/*
 * Physical to virtual address translation.
 *
 * Given the physical (DMA) address for a character buffer, this function
 * returns the virtual equivalent.
 */
static inline void *qe2cpu_addr(dma_addr_t addr, struct uart_qe_port *qe_port)
{}

/*
 * Return 1 if the QE is done transmitting all buffers for this port
 *
 * This function scans each BD in sequence.  If we find a BD that is not
 * ready (READY=1), then we return 0 indicating that the QE is still sending
 * data.  If we reach the last BD (WRAP=1), then we know we've scanned
 * the entire list, and all BDs are done.
 */
static unsigned int qe_uart_tx_empty(struct uart_port *port)
{}

/*
 * Set the modem control lines
 *
 * Although the QE can control the modem control lines (e.g. CTS), we
 * don't need that support. This function must exist, however, otherwise
 * the kernel will panic.
 */
static void qe_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{}

/*
 * Get the current modem control line status
 *
 * Although the QE can control the modem control lines (e.g. CTS), this
 * driver currently doesn't support that, so we always return Carrier
 * Detect, Data Set Ready, and Clear To Send.
 */
static unsigned int qe_uart_get_mctrl(struct uart_port *port)
{}

/*
 * Disable the transmit interrupt.
 *
 * Although this function is called "stop_tx", it does not actually stop
 * transmission of data.  Instead, it tells the QE to not generate an
 * interrupt when the UCC is finished sending characters.
 */
static void qe_uart_stop_tx(struct uart_port *port)
{}

/*
 * Transmit as many characters to the HW as possible.
 *
 * This function will attempt to stuff of all the characters from the
 * kernel's transmit buffer into TX BDs.
 *
 * A return value of non-zero indicates that it successfully stuffed all
 * characters from the kernel buffer.
 *
 * A return value of zero indicates that there are still characters in the
 * kernel's buffer that have not been transmitted, but there are no more BDs
 * available.  This function should be called again after a BD has been made
 * available.
 */
static int qe_uart_tx_pump(struct uart_qe_port *qe_port)
{}

/*
 * Start transmitting data
 *
 * This function will start transmitting any available data, if the port
 * isn't already transmitting data.
 */
static void qe_uart_start_tx(struct uart_port *port)
{}

/*
 * Stop transmitting data
 */
static void qe_uart_stop_rx(struct uart_port *port)
{}

/* Start or stop sending  break signal
 *
 * This function controls the sending of a break signal.  If break_state=1,
 * then we start sending a break signal.  If break_state=0, then we stop
 * sending the break signal.
 */
static void qe_uart_break_ctl(struct uart_port *port, int break_state)
{}

/* ISR helper function for receiving character.
 *
 * This function is called by the ISR to handling receiving characters
 */
static void qe_uart_int_rx(struct uart_qe_port *qe_port)
{}

/* Interrupt handler
 *
 * This interrupt handler is called after a BD is processed.
 */
static irqreturn_t qe_uart_int(int irq, void *data)
{}

/* Initialize buffer descriptors
 *
 * This function initializes all of the RX and TX buffer descriptors.
 */
static void qe_uart_initbd(struct uart_qe_port *qe_port)
{}

/*
 * Initialize a UCC for UART.
 *
 * This function configures a given UCC to be used as a UART device. Basic
 * UCC initialization is handled in qe_uart_request_port().  This function
 * does all the UART-specific stuff.
 */
static void qe_uart_init_ucc(struct uart_qe_port *qe_port)
{}

/*
 * Initialize the port.
 */
static int qe_uart_startup(struct uart_port *port)
{}

/*
 * Shutdown the port.
 */
static void qe_uart_shutdown(struct uart_port *port)
{}

/*
 * Set the serial port parameters.
 */
static void qe_uart_set_termios(struct uart_port *port,
				struct ktermios *termios,
				const struct ktermios *old)
{}

/*
 * Return a pointer to a string that describes what kind of port this is.
 */
static const char *qe_uart_type(struct uart_port *port)
{}

/*
 * Allocate any memory and I/O resources required by the port.
 */
static int qe_uart_request_port(struct uart_port *port)
{}

/*
 * Configure the port.
 *
 * We say we're a CPM-type port because that's mostly true.  Once the device
 * is configured, this driver operates almost identically to the CPM serial
 * driver.
 */
static void qe_uart_config_port(struct uart_port *port, int flags)
{}

/*
 * Release any memory and I/O resources that were allocated in
 * qe_uart_request_port().
 */
static void qe_uart_release_port(struct uart_port *port)
{}

/*
 * Verify that the data in serial_struct is suitable for this device.
 */
static int qe_uart_verify_port(struct uart_port *port,
			       struct serial_struct *ser)
{}
/* UART operations
 *
 * Details on these functions can be found in Documentation/driver-api/serial/driver.rst
 */
static const struct uart_ops qe_uart_pops =;


#ifdef CONFIG_PPC32
/*
 * Obtain the SOC model number and revision level
 *
 * This function parses the device tree to obtain the SOC model.  It then
 * reads the SVR register to the revision.
 *
 * The device tree stores the SOC model two different ways.
 *
 * The new way is:
 *
 *      	cpu@0 {
 *      		compatible = "PowerPC,8323";
 *      		device_type = "cpu";
 *      		...
 *
 *
 * The old way is:
 *      	 PowerPC,8323@0 {
 *      		device_type = "cpu";
 *      		...
 *
 * This code first checks the new way, and then the old way.
 */
static unsigned int soc_info(unsigned int *rev_h, unsigned int *rev_l)
{
	struct device_node *np;
	const char *soc_string;
	unsigned int svr;
	unsigned int soc;

	/* Find the CPU node */
	np = of_find_node_by_type(NULL, "cpu");
	if (!np)
		return 0;
	/* Find the compatible property */
	soc_string = of_get_property(np, "compatible", NULL);
	if (!soc_string)
		/* No compatible property, so try the name. */
		soc_string = np->name;

	of_node_put(np);

	/* Extract the SOC number from the "PowerPC," string */
	if ((sscanf(soc_string, "PowerPC,%u", &soc) != 1) || !soc)
		return 0;

	/* Get the revision from the SVR */
	svr = mfspr(SPRN_SVR);
	*rev_h = (svr >> 4) & 0xf;
	*rev_l = svr & 0xf;

	return soc;
}

/*
 * requst_firmware_nowait() callback function
 *
 * This function is called by the kernel when a firmware is made available,
 * or if it times out waiting for the firmware.
 */
static void uart_firmware_cont(const struct firmware *fw, void *context)
{
	struct qe_firmware *firmware;
	struct device *dev = context;
	int ret;

	if (!fw) {
		dev_err(dev, "firmware not found\n");
		return;
	}

	firmware = (struct qe_firmware *) fw->data;

	if (be32_to_cpu(firmware->header.length) != fw->size) {
		dev_err(dev, "invalid firmware\n");
		goto out;
	}

	ret = qe_upload_firmware(firmware);
	if (ret) {
		dev_err(dev, "could not load firmware\n");
		goto out;
	}

	firmware_loaded = 1;
 out:
	release_firmware(fw);
}

static int soft_uart_init(struct platform_device *ofdev)
{
	struct device_node *np = ofdev->dev.of_node;
	struct qe_firmware_info *qe_fw_info;
	int ret;

	if (of_property_read_bool(np, "soft-uart")) {
		dev_dbg(&ofdev->dev, "using Soft-UART mode\n");
		soft_uart = 1;
	} else {
		return 0;
	}

	qe_fw_info = qe_get_firmware_info();

	/* Check if the firmware has been uploaded. */
	if (qe_fw_info && strstr(qe_fw_info->id, "Soft-UART")) {
		firmware_loaded = 1;
	} else {
		char filename[32];
		unsigned int soc;
		unsigned int rev_h;
		unsigned int rev_l;

		soc = soc_info(&rev_h, &rev_l);
		if (!soc) {
			dev_err(&ofdev->dev, "unknown CPU model\n");
			return -ENXIO;
		}
		sprintf(filename, "fsl_qe_ucode_uart_%u_%u%u.bin",
			soc, rev_h, rev_l);

		dev_info(&ofdev->dev, "waiting for firmware %s\n",
			 filename);

		/*
		 * We call request_firmware_nowait instead of
		 * request_firmware so that the driver can load and
		 * initialize the ports without holding up the rest of
		 * the kernel.  If hotplug support is enabled in the
		 * kernel, then we use it.
		 */
		ret = request_firmware_nowait(THIS_MODULE,
					      FW_ACTION_UEVENT, filename, &ofdev->dev,
					      GFP_KERNEL, &ofdev->dev, uart_firmware_cont);
		if (ret) {
			dev_err(&ofdev->dev,
				"could not load firmware %s\n",
				filename);
			return ret;
		}
	}
	return 0;
}

#else /* !CONFIG_PPC32 */

static int soft_uart_init(struct platform_device *ofdev)
{}

#endif


static int ucc_uart_probe(struct platform_device *ofdev)
{}

static void ucc_uart_remove(struct platform_device *ofdev)
{}

static const struct of_device_id ucc_uart_match[] =;
MODULE_DEVICE_TABLE(of, ucc_uart_match);

static struct platform_driver ucc_uart_of_driver =;

static int __init ucc_uart_init(void)
{}

static void __exit ucc_uart_exit(void)
{}

module_init();
module_exit(ucc_uart_exit);

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();
MODULE_ALIAS_CHARDEV_MAJOR();