Skip to content

Commit

Permalink
serial: 8250: Add support for higher baud rates to Pericom chips
Browse files Browse the repository at this point in the history
The Pericom chips can achieve additional baud rates by programming the
sample clock register. The baud rates can be described as
921600 * 16 / (16 - scr) for scr values 5 to 15. The divisor is set to 1
for these baud rates.

Adds new quirk for Pericom chips other than the four port chips to use
the

Signed-off-by: Jay Dolan <jay.dolan@accesio.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Jay Dolan authored and Greg Kroah-Hartman committed Jun 18, 2019
1 parent 4e828c3 commit 6bf4e42
Showing 1 changed file with 79 additions and 18 deletions.
97 changes: 79 additions & 18 deletions drivers/tty/serial/8250/8250_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1326,13 +1326,66 @@ static int pci_default_setup(struct serial_private *priv,

return setup_port(priv, port, bar, offset, board->reg_shift);
}

void
pericom_do_set_divisor(struct uart_port *port, unsigned int baud,
unsigned int quot, unsigned int quot_frac)
{
int scr;
int lcr;
int actual_baud;
int tolerance;

for (scr = 5 ; scr <= 15 ; scr++) {
actual_baud = 921600 * 16 / scr;
tolerance = actual_baud / 50;

if ((baud < actual_baud + tolerance) &&
(baud > actual_baud - tolerance)) {

lcr = serial_port_in(port, UART_LCR);
serial_port_out(port, UART_LCR, lcr | 0x80);

serial_port_out(port, UART_DLL, 1);
serial_port_out(port, UART_DLM, 0);
serial_port_out(port, 2, 16 - scr);
serial_port_out(port, UART_LCR, lcr);
return;
} else if (baud > actual_baud) {
break;
}
}
serial8250_do_set_divisor(port, baud, quot, quot_frac);
}
static int pci_pericom_setup(struct serial_private *priv,
const struct pciserial_board *board,
struct uart_8250_port *port, int idx)
{
unsigned int bar, offset = board->first_offset, maxnr;

bar = FL_GET_BASE(board->flags);
if (board->flags & FL_BASE_BARS)
bar += idx;
else
offset += idx * board->uart_offset;


maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) >>
(board->reg_shift + 3);

if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr)
return 1;

port->port.set_divisor = pericom_do_set_divisor;

return setup_port(priv, port, bar, offset, board->reg_shift);
}

static int pci_pericom_setup_four_at_eight(struct serial_private *priv,
const struct pciserial_board *board,
struct uart_8250_port *port, int idx)
{
unsigned int bar, offset = board->first_offset, maxnr;

bar = FL_GET_BASE(board->flags);
if (board->flags & FL_BASE_BARS)
bar += idx;
Expand All @@ -1348,6 +1401,8 @@ static int pci_pericom_setup(struct serial_private *priv,
if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr)
return 1;

port->port.set_divisor = pericom_do_set_divisor;

return setup_port(priv, port, bar, offset, board->reg_shift);
}

Expand Down Expand Up @@ -1995,7 +2050,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.device = PCI_DEVICE_ID_PERICOM_PI7C9X7954,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup,
.setup = pci_pericom_setup_four_at_eight,
},
/*
* PLX
Expand Down Expand Up @@ -2032,107 +2087,113 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.device = PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SDB,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup,
.setup = pci_pericom_setup_four_at_eight,
},
{
.vendor = PCI_VENDOR_ID_ACCESIO,
.device = PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4S,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup,
.setup = pci_pericom_setup_four_at_eight,
},
{
.vendor = PCI_VENDOR_ID_ACCESIO,
.device = PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4DB,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup,
.setup = pci_pericom_setup_four_at_eight,
},
{
.vendor = PCI_VENDOR_ID_ACCESIO,
.device = PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_4,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup,
.setup = pci_pericom_setup_four_at_eight,
},
{
.vendor = PCI_VENDOR_ID_ACCESIO,
.device = PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SMDB,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup,
.setup = pci_pericom_setup_four_at_eight,
},
{
.vendor = PCI_VENDOR_ID_ACCESIO,
.device = PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4SM,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup,
.setup = pci_pericom_setup_four_at_eight,
},
{
.vendor = PCI_VENDOR_ID_ACCESIO,
.device = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_4,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup,
.setup = pci_pericom_setup_four_at_eight,
},
{
.vendor = PCI_VENDOR_ID_ACCESIO,
.device = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_4,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup,
.setup = pci_pericom_setup_four_at_eight,
},
{
.vendor = PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4S,
.device = PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_4,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup,
.setup = pci_pericom_setup_four_at_eight,
},
{
.vendor = PCI_VENDOR_ID_ACCESIO,
.device = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_4,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup,
.setup = pci_pericom_setup_four_at_eight,
},
{
.vendor = PCI_VENDOR_ID_ACCESIO,
.device = PCI_DEVICE_ID_ACCESIO_PCIE_COM422_4,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup,
.setup = pci_pericom_setup_four_at_eight,
},
{
.vendor = PCI_VENDOR_ID_ACCESIO,
.device = PCI_DEVICE_ID_ACCESIO_PCIE_COM485_4,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup,
.setup = pci_pericom_setup_four_at_eight,
},
{
.vendor = PCI_VENDOR_ID_ACCESIO,
.device = PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup,
.setup = pci_pericom_setup_four_at_eight,
},
{
.vendor = PCI_VENDOR_ID_ACCESIO,
.device = PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SM,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup,
.setup = pci_pericom_setup_four_at_eight,
},
{
.vendor = PCI_VENDOR_ID_ACCESIO,
.device = PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4SM,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup,
.setup = pci_pericom_setup_four_at_eight,
},
/*
{
.vendor = PCI_VENDOR_ID_ACCESIO,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_pericom_setup,
}, /*
* SBS Technologies, Inc., PMC-OCTALPRO 232
*/
{
Expand Down

0 comments on commit 6bf4e42

Please sign in to comment.