2015-07-27 12:19:36 -04:00
|
|
|
/* board.h - board configuration macros for the ia32_pci platform */
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (c) 2013-2015, Wind River Systems, Inc.
|
|
|
|
*
|
2015-10-06 11:00:37 -05:00
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
2015-04-10 16:44:37 -07:00
|
|
|
*
|
2015-10-06 11:00:37 -05:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2015-04-10 16:44:37 -07:00
|
|
|
*
|
2015-10-06 11:00:37 -05:00
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
2015-04-10 16:44:37 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2015-10-20 09:42:33 -07:00
|
|
|
* DESCRIPTION
|
|
|
|
* This header file is used to specify and describe board-level aspects for
|
|
|
|
* the 'ia32_pci' platform.
|
2015-07-01 17:22:39 -04:00
|
|
|
*/
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
#ifndef __INCboardh
|
|
|
|
#define __INCboardh
|
|
|
|
|
|
|
|
#include <misc/util.h>
|
|
|
|
|
|
|
|
#ifndef _ASMLANGUAGE
|
2015-08-05 12:13:36 -07:00
|
|
|
#include <device.h>
|
2015-04-10 16:44:37 -07:00
|
|
|
#include <drivers/rand32.h>
|
|
|
|
#endif
|
|
|
|
|
2015-08-27 16:57:30 +03:00
|
|
|
#ifdef CONFIG_IOAPIC
|
|
|
|
#include <drivers/ioapic.h>
|
|
|
|
#ifdef CONFIG_SERIAL_INTERRUPT_LEVEL
|
|
|
|
#ifdef CONFIG_SERIAL_INTERRUPT_LOW
|
|
|
|
#define UART_IOAPIC_FLAGS (IOAPIC_LEVEL | IOAPIC_LOW)
|
|
|
|
#else
|
|
|
|
#define UART_IOAPIC_FLAGS (IOAPIC_LEVEL)
|
|
|
|
#endif
|
|
|
|
#else /* edge triggered interrupt */
|
|
|
|
#ifdef CONFIG_SERIAL_INTERRUPT_LOW
|
|
|
|
/* generate interrupt on falling edge */
|
|
|
|
#define UART_IOAPIC_FLAGS (IOAPIC_LOW)
|
|
|
|
#else
|
|
|
|
/* generate interrupt on raising edge */
|
|
|
|
#define UART_IOAPIC_FLAGS (0)
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2015-08-10 16:04:39 -04:00
|
|
|
#define NUM_STD_IRQS 16 /* number of "standard" IRQs on an x86 platform */
|
2015-04-10 16:44:37 -07:00
|
|
|
#define INT_VEC_IRQ0 0x20 /* Vector number for IRQ0 */
|
|
|
|
|
|
|
|
/* serial port (aka COM port) information */
|
|
|
|
#define COM1_BAUD_RATE 115200
|
|
|
|
|
|
|
|
#define COM2_BAUD_RATE 115200
|
|
|
|
#define COM2_INT_LVL 0x11 /* COM2 connected to IRQ17 */
|
|
|
|
|
|
|
|
#define UART_REG_ADDR_INTERVAL 4 /* address diff of adjacent regs. */
|
|
|
|
#define UART_XTAL_FREQ (2764800 * 16)
|
|
|
|
|
|
|
|
/* uart configuration settings */
|
|
|
|
|
|
|
|
/* Generic definitions */
|
2015-05-20 14:35:45 +03:00
|
|
|
#define CONFIG_UART_PCI_VENDOR_ID 0x8086
|
|
|
|
#define CONFIG_UART_PCI_DEVICE_ID 0x0936
|
2015-08-27 11:06:15 +03:00
|
|
|
#define CONFIG_UART_PCI_BUS 0
|
|
|
|
#define CONFIG_UART_PCI_DEV 20
|
|
|
|
#define CONFIG_UART_PORT_0_FUNCTION 1
|
|
|
|
#define CONFIG_UART_PORT_1_FUNCTION 5
|
2015-05-25 17:35:58 -04:00
|
|
|
#define CONFIG_UART_PCI_BAR 0
|
2015-04-10 16:44:37 -07:00
|
|
|
#define CONFIG_UART_BAUDRATE COM1_BAUD_RATE
|
|
|
|
|
2015-08-05 12:13:36 -07:00
|
|
|
#ifndef _ASMLANGUAGE
|
2015-08-10 15:02:04 -07:00
|
|
|
extern struct device * const uart_devs[];
|
|
|
|
#endif
|
2015-08-05 12:13:36 -07:00
|
|
|
|
2015-08-12 10:33:56 -07:00
|
|
|
#if defined(CONFIG_UART_CONSOLE)
|
|
|
|
|
2015-08-20 12:18:24 +03:00
|
|
|
#define CONFIG_UART_CONSOLE_IRQ COM2_INT_LVL
|
|
|
|
#define CONFIG_UART_CONSOLE_INT_PRI 3
|
|
|
|
|
2015-08-10 15:02:04 -07:00
|
|
|
#define UART_CONSOLE_DEV (uart_devs[CONFIG_UART_CONSOLE_INDEX])
|
2015-08-05 12:13:36 -07:00
|
|
|
|
2015-08-12 10:33:56 -07:00
|
|
|
#endif /* CONFIG_UART_CONSOLE */
|
|
|
|
|
2015-09-11 14:47:11 +03:00
|
|
|
#ifdef CONFIG_GPIO_DW_0
|
|
|
|
#if defined(CONFIG_GPIO_DW_0_FALLING_EDGE)
|
|
|
|
#define GPIO_DW_0_IRQ_IOAPIC_FLAGS (IOAPIC_EDGE | IOAPIC_LOW)
|
|
|
|
#elif defined(CONFIG_GPIO_DW_0_RISING_EDGE)
|
|
|
|
#define GPIO_DW_0_IRQ_IOAPIC_FLAGS (IOAPIC_EDGE | IOAPIC_HIGH)
|
|
|
|
#elif defined(CONFIG_GPIO_DW_0_LEVEL_HIGH)
|
|
|
|
#define GPIO_DW_0_IRQ_IOAPIC_FLAGS (IOAPIC_LEVEL | IOAPIC_HIGH)
|
|
|
|
#elif defined(CONFIG_GPIO_DW_0_LEVEL_LOW)
|
|
|
|
#define GPIO_DW_0_IRQ_IOAPIC_FLAGS (IOAPIC_LEVEL | IOAPIC_LOW)
|
|
|
|
#endif
|
|
|
|
#endif /* GPIO_DW_0 */
|
|
|
|
|
2015-08-20 12:06:21 +03:00
|
|
|
/* Bluetooth UART definitions */
|
|
|
|
#if defined(CONFIG_BLUETOOTH_UART)
|
|
|
|
|
|
|
|
#define CONFIG_BLUETOOTH_UART_INDEX 1
|
|
|
|
#define CONFIG_BLUETOOTH_UART_IRQ COM2_INT_LVL
|
|
|
|
#define CONFIG_BLUETOOTH_UART_INT_PRI 3
|
|
|
|
#define CONFIG_BLUETOOTH_UART_FREQ UART_XTAL_FREQ
|
|
|
|
#define CONFIG_BLUETOOTH_UART_BAUDRATE CONFIG_UART_BAUDRATE
|
|
|
|
#define BT_UART_DEV (uart_devs[CONFIG_BLUETOOTH_UART_INDEX])
|
|
|
|
|
|
|
|
#endif /* CONFIG_BLUETOOTH_UART */
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2015-09-29 11:22:23 -07:00
|
|
|
#ifdef CONFIG_I2C_DW
|
2015-09-10 14:25:30 -07:00
|
|
|
|
|
|
|
#include <drivers/ioapic.h>
|
|
|
|
|
2015-09-29 11:22:23 -07:00
|
|
|
#if defined(CONFIG_I2C_DW_IRQ_FALLING_EDGE)
|
|
|
|
#define I2C_DW_IRQ_IOAPIC_FLAGS (IOAPIC_EDGE | IOAPIC_LOW)
|
|
|
|
#elif defined(CONFIG_I2C_DW_IRQ_RISING_EDGE)
|
|
|
|
#define I2C_DW_IRQ_IOAPIC_FLAGS (IOAPIC_EDGE | IOAPIC_HIGH)
|
|
|
|
#elif defined(CONFIG_I2C_DW_IRQ_LEVEL_HIGH)
|
|
|
|
#define I2C_DW_IRQ_IOAPIC_FLAGS (IOAPIC_LEVEL | IOAPIC_HIGH)
|
|
|
|
#elif defined(CONFIG_I2C_DW_IRQ_LEVEL_LOW)
|
|
|
|
#define I2C_DW_IRQ_IOAPIC_FLAGS (IOAPIC_LEVEL | IOAPIC_LOW)
|
2015-09-10 14:25:30 -07:00
|
|
|
#endif
|
|
|
|
|
2015-09-19 23:37:42 -04:00
|
|
|
#endif /* CONFIG_I2C_DW_0 */
|
2015-09-10 14:25:30 -07:00
|
|
|
|
2015-09-24 13:08:41 +03:00
|
|
|
#ifdef CONFIG_SPI_INTEL
|
|
|
|
#if defined(CONFIG_SPI_INTEL_FALLING_EDGE)
|
|
|
|
#define SPI_INTEL_IRQ_IOAPIC_FLAGS (IOAPIC_EDGE | IOAPIC_LOW)
|
|
|
|
#elif defined(CONFIG_SPI_INTEL_RISING_EDGE)
|
|
|
|
#define SPI_INTEL_IRQ_IOAPIC_FLAGS (IOAPIC_EDGE | IOAPIC_HIGH)
|
|
|
|
#elif defined(CONFIG_SPI_INTEL_LEVEL_HIGH)
|
|
|
|
#define SPI_INTEL_IRQ_IOAPIC_FLAGS (IOAPIC_LEVEL | IOAPIC_HIGH)
|
|
|
|
#elif defined(CONFIG_SPI_INTEL_LEVEL_LOW)
|
|
|
|
#define SPI_INTEL_IRQ_IOAPIC_FLAGS (IOAPIC_LEVEL | IOAPIC_LOW)
|
|
|
|
#endif
|
|
|
|
#endif /* CONFIG_SPI_INTEL */
|
|
|
|
|
2015-04-10 16:44:37 -07:00
|
|
|
/*
|
|
|
|
* The irq_connect() API connects to a (virtualized) IRQ and the
|
|
|
|
* associated interrupt controller is programmed with the allocated vector.
|
|
|
|
* The Quark board virtualizes IRQs as follows:
|
|
|
|
*
|
2015-07-28 14:39:12 -04:00
|
|
|
* - The first CONFIG_IOAPIC_NUM_RTES IRQs are provided by the IOAPIC
|
2015-04-10 16:44:37 -07:00
|
|
|
* - The remaining IRQs are provided by the LOAPIC.
|
|
|
|
*
|
|
|
|
* Thus, for example, if the IOAPIC supports 24 IRQs:
|
|
|
|
*
|
|
|
|
* - IRQ0 to IRQ23 map to IOAPIC IRQ0 to IRQ23
|
|
|
|
* - IRQ24 to IRQ29 map to LOAPIC LVT entries as follows:
|
|
|
|
*
|
|
|
|
* IRQ24 -> LOAPIC_TIMER
|
|
|
|
* IRQ25 -> LOAPIC_THERMAL
|
|
|
|
* IRQ26 -> LOAPIC_PMC
|
|
|
|
* IRQ27 -> LOAPIC_LINT0
|
|
|
|
* IRQ28 -> LOAPIC_LINT1
|
|
|
|
* IRQ29 -> LOAPIC_ERROR
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* PCI definitions */
|
pci: Provide a simpler yet powerful PCI enumeration API
This fixes many issues around PCI enumeration from old API:
- a static internal table was fed with scanning results, thus eating
memory, and worse: due to the limit of its size, scanning for new
classes was impossible unless growing statically the size of this
table --> more memory eaten! Not to mention PCI enumeration is done
once at boot time for driver initialization and that's all, so this
table is hanging around for nothing afterwards.
- one needs first to scan a class, then maybe he will be able to find
his device via pci_dev_find. Where all could be done at once.
- pci_dev_find was not trustworthy due again to the internal table. Now
if the device is not found, one will know it really went through all
the possbilities.
- still let the possibility for hard-coded BARs value on driver side
(thus no PCI scan required). However this is greatly advised not to do
so as BARs might change over a firmware/BIOS update.
Comparison:
old pci_dev_scan: could only filter out via class mask.
new pci_dev_scan: can filter out via a class, a vendor and device ID
(it could easily do the same for Function and BAR index as these are
usually fixed and informed through datasheet)
old pci_dev_scan: was limited in its findings by the size of the
internal result table.
new pci_dev_scan: can proceed through all the buses and devices every
time (there are optimizations to avoid useless work of course)
old results did not tell about the function or BAR index.
new one tells, and the structure has not bloated.
old internal code: was storing a big table of results
new internal code: is only storing a small lookup structure and an
array of Bus:Dev pairs for each PCI class for optimizations purpose.
(though, if needed, we could disable this through some #ifdef)
Usage:
- Have a local struct dev_info
- Fill it with what you want to look for, currently: only class and
vendor_id/device_id. Function and BAR index could be added if needed.
- Call pci_bus_scan_init(): this will reset the internal lookup
structure.
- Call pci_dev_scan(<a pointer to your dev_info>): at first call, the
internal lookup structure will pick up the informations from dev_info
and will try to find out what has been requested. It will return 1 on
success, or 0. On 1, your dev_info structure will be updated with the
found informations. If more devices can be found against the same
lookup informations, just call again pci_dev_scan(<a pointer to your
dev_info>) as long as it returns 1. When 0 is hit, it will mean you
found all.
Change-Id: Ibc2a16c4485ee3fed7ef4946af0ece032ae406e4
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
2015-05-20 14:30:35 +03:00
|
|
|
#define PCI_BUS_NUMBERS 2
|
|
|
|
|
2015-04-10 16:44:37 -07:00
|
|
|
#define PCI_CTRL_ADDR_REG 0xCF8
|
|
|
|
#define PCI_CTRL_DATA_REG 0xCFC
|
|
|
|
|
|
|
|
#define PCI_INTA 1
|
|
|
|
#define PCI_INTB 2
|
|
|
|
#define PCI_INTC 3
|
|
|
|
#define PCI_INTD 4
|
|
|
|
|
|
|
|
|
2015-07-01 17:22:39 -04:00
|
|
|
/**
|
|
|
|
*
|
2015-07-01 17:51:40 -04:00
|
|
|
* @brief Convert PCI interrupt PIN to IRQ
|
2015-07-01 17:22:39 -04:00
|
|
|
*
|
|
|
|
* The routine uses "standard design consideration" and implies that
|
|
|
|
* INTA (pin 1) -> IRQ 16
|
|
|
|
* INTB (pin 2) -> IRQ 17
|
|
|
|
* INTC (pin 3) -> IRQ 18
|
|
|
|
* INTD (pin 4) -> IRQ 19
|
|
|
|
*
|
2015-07-01 17:29:04 -04:00
|
|
|
* @return IRQ number, -1 if the result is incorrect
|
2015-07-01 17:22:39 -04:00
|
|
|
*
|
|
|
|
*/
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
static inline int pci_pin2irq(int pin)
|
|
|
|
{
|
|
|
|
if ((pin < PCI_INTA) || (pin > PCI_INTD))
|
|
|
|
return -1;
|
2015-08-10 16:04:39 -04:00
|
|
|
return NUM_STD_IRQS + pin - 1;
|
2015-04-10 16:44:37 -07:00
|
|
|
}
|
|
|
|
|
2015-07-01 17:22:39 -04:00
|
|
|
/**
|
|
|
|
*
|
2015-07-01 17:51:40 -04:00
|
|
|
* @brief Convert IRQ to PCI interrupt pin
|
2015-07-01 17:22:39 -04:00
|
|
|
*
|
2015-07-01 17:29:04 -04:00
|
|
|
* @return pin number, -1 if the result is incorrect
|
2015-07-01 17:22:39 -04:00
|
|
|
*
|
|
|
|
*/
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
static inline int pci_irq2pin(int irq)
|
|
|
|
{
|
2015-08-10 16:04:39 -04:00
|
|
|
if ((irq < NUM_STD_IRQS) || (irq > NUM_STD_IRQS + PCI_INTD - 1))
|
2015-04-10 16:44:37 -07:00
|
|
|
return -1;
|
2015-08-10 16:04:39 -04:00
|
|
|
return irq - NUM_STD_IRQS + 1;
|
2015-04-10 16:44:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
extern void _SysIntVecProgram(unsigned int vector, unsigned int);
|
|
|
|
|
|
|
|
#endif /* __INCboardh */
|