Convert Marvell ARM platforms to FDT convention.

The following systems are involved:

  - DB-88F5182
  - DB-88F5281
  - DB-88F6281
  - DB-78100
  - SheevaPlug

This overhaul covers the following major changes:

  - All integrated peripherals drivers for Marvell ARM SoC, which are
    currently in the FreeBSD source tree are reworked and adjusted so they
    derive config data out of the device tree blob (instead of hard coded /
    tabelarized values).

  - Since the common FDT infrastrucutre (fdtbus, simplebus) is used we say
    good by to obio / mbus drivers and numerous hard-coded config data.

Note that world needs to be built WITH_FDT for the affected platforms.

Reviewed by:	imp
Sponsored by:	The FreeBSD Foundation.
This commit is contained in:
Rafal Jaworowski 2010-06-13 13:28:53 +00:00
parent dc65d002dd
commit db5ef4fc77
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=209131
40 changed files with 1756 additions and 2695 deletions

View File

@ -83,3 +83,7 @@ device ds133x
# SATA
device ata
device atadisk
# Flattened Device Tree
options FDT
makeoptions FDT_DTS_FILE=db78100.dts

View File

@ -85,3 +85,7 @@ device da
# SATA
device ata
device atadisk
# Flattened Device Tree
options FDT
makeoptions FDT_DTS_FILE=db88f5281.dts

View File

@ -82,3 +82,7 @@ device iicbus
# SATA
device ata
device atadisk
# Flattened Device Tree
options FDT
makeoptions FDT_DTS_FILE=db88f6281.dts

View File

@ -69,3 +69,7 @@ device scbus
device pass
device da
# Flattened Device Tree
options FDT
options FDT_DTB_STATIC
makeoptions FDT_DTS_FILE=sheevaplug.dts

View File

@ -1,72 +0,0 @@
/*-
* Copyright (C) 2006-2008 Semihalf, Marian Balakowicz <m8@semihalf.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_BOOTINFO_H_
#define _MACHINE_BOOTINFO_H_
#if !defined(LOCORE)
/* Platform hardware spec, received from loader(8) */
#define BI_VERSION 1
struct bi_mem_region {
vm_paddr_t mem_base;
vm_size_t mem_size;
};
struct bi_eth_addr {
u_int8_t mac_addr[6];
u_int8_t padding[2];
};
struct bootinfo {
u_int32_t bi_version;
vm_offset_t bi_bar_base;
u_int32_t bi_cpu_clk;
u_int32_t bi_bus_clk;
u_int8_t bi_mem_reg_no;
u_int8_t bi_eth_addr_no;
u_int8_t padding[2];
u_int8_t bi_data[1];
/*
* The bi_data container is allocated in run time and has the
* following layout:
*
* - bi_mem_reg_no elements of struct bi_mem_region
* - bi_eth_addr_no elements of struct bi_eth_addr
*/
};
extern struct bootinfo *bootinfo;
struct bi_mem_region *bootinfo_mr(void);
struct bi_eth_addr *bootinfo_eth(void);
#endif
#endif /* _MACHINE_BOOTINFO_H_ */

View File

@ -29,7 +29,6 @@
#ifndef _MACHINE_METADATA_H_
#define _MACHINE_METADATA_H_
#define MODINFOMD_BOOTINFO 0x1001
#define MODINFOMD_DTBP 0x1002
#define MODINFOMD_DTBP 0x1001
#endif /* !_MACHINE_METADATA_H_ */

View File

@ -49,7 +49,7 @@ bs_protos(generic);
bs_protos(generic_armv4);
/*
* The obio bus space tag. This is constant for all instances, so
* The bus space tag. This is constant for all instances, so
* we never have to explicitly "create" it.
*/
static struct bus_space _base_tag = {
@ -159,4 +159,4 @@ static struct bus_space _base_tag = {
NULL
};
bus_space_tag_t obio_tag = &_base_tag;
bus_space_tag_t fdtbus_bs_tag = &_base_tag;

File diff suppressed because it is too large Load Diff

View File

@ -1,162 +0,0 @@
/*-
* Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
* All rights reserved.
*
* Developed by Semihalf.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of MARVELL nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/bus.h>
#include <machine/pte.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
#include <arm/mv/mvreg.h>
#include <arm/mv/mvvar.h>
#include <arm/mv/mvwin.h>
/*
* Virtual address space layout:
* -----------------------------
* 0x0000_0000 - 0xbfff_ffff : user process
*
* 0xc040_0000 - virtual_avail : kernel reserved (text, data, page tables
* : structures, ARM stacks etc.)
* virtual_avail - 0xefff_ffff : KVA (virtual_avail is typically < 0xc0a0_0000)
* 0xf000_0000 - 0xf0ff_ffff : no-cache allocation area (16MB)
* 0xf100_0000 - 0xf10f_ffff : SoC integrated devices registers range (1MB)
* 0xf110_0000 - 0xf11f_ffff : PCI-Express I/O space (1MB)
* 0xf120_0000 - 0xf12f_ffff : unused (1MB)
* 0xf130_0000 - 0xf52f_ffff : PCI-Express memory space (64MB)
* 0xf930_0000 - 0xfffe_ffff : unused (~172MB)
* 0xffff_0000 - 0xffff_0fff : 'high' vectors page (4KB)
* 0xffff_1000 - 0xffff_1fff : ARM_TP_ADDRESS/RAS page (4KB)
* 0xffff_2000 - 0xffff_ffff : unused (~55KB)
*/
/* Static device mappings. */
const struct pmap_devmap pmap_devmap[] = {
/*
* Map the on-board devices VA == PA so that we can access them
* with the MMU on or off.
*/
{ /* SoC integrated peripherals registers range */
MV_BASE,
MV_PHYS_BASE,
MV_SIZE,
VM_PROT_READ | VM_PROT_WRITE,
PTE_NOCACHE,
},
{ /* PCIE I/O */
MV_PCIE_IO_BASE,
MV_PCIE_IO_PHYS_BASE,
MV_PCIE_IO_SIZE,
VM_PROT_READ | VM_PROT_WRITE,
PTE_NOCACHE,
},
{ /* PCIE Memory */
MV_PCIE_MEM_BASE,
MV_PCIE_MEM_PHYS_BASE,
MV_PCIE_MEM_SIZE,
VM_PROT_READ | VM_PROT_WRITE,
PTE_NOCACHE,
},
{ 0, 0, 0, 0, 0, }
};
const struct gpio_config mv_gpio_config[] = {
{ -1, -1, -1 }
};
void
platform_mpp_init(void)
{
/*
* MPP Configuration for DB-78100-BP
*
* MPP[0]: GE1_TXCLK
* MPP[1]: GE1_TXCTL
* MPP[2]: GE1_RXCTL
* MPP[3]: GE1_RXCLK
* MPP[4]: GE1_TXD[0]
* MPP[5]: GE1_TXD[1]
* MPP[6]: GE1_TXD[2]
* MPP[7]: GE1_TXD[3]
* MPP[8]: GE1_RXD[0]
* MPP[9]: GE1_RXD[1]
* MPP[10]: GE1_RXD[2]
* MPP[11]: GE1_RXD[3]
* MPP[13]: SYSRST_OUTn
* MPP[14]: SATA1_ACT
* MPP[15]: SATA0_ACT
* MPP[16]: UA2_TXD
* MPP[17]: UA2_RXD
* MPP[18]: <UNKNOWN>
* MPP[19]: <UNKNOWN>
* MPP[20]: <UNKNOWN>
* MPP[21]: <UNKNOWN>
* MPP[22]: UA3_TXD
* MPP[23]: UA3_RXD
* MPP[48]: <UNKNOWN>
* MPP[49]: <UNKNOWN>
*
* Others: GPIO
*
* <UNKNOWN> entries are not documented, not on the schematics etc.
*/
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL0, 0x22222222);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL1, 0x33302222);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL2, 0x44333344);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL3, 0x00000000);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL4, 0x00000000);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL5, 0x00000000);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL6, 0x0000FFFF);
}
static void
platform_identify(void *dummy)
{
soc_identify();
/*
* XXX Board identification e.g. read out from FPGA or similar should
* go here
*/
}
SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify, NULL);

View File

@ -37,166 +37,12 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <machine/bus.h>
#include <machine/fdt.h>
#include <arm/mv/mvreg.h>
#include <arm/mv/mvvar.h>
#include <arm/mv/mvwin.h>
#define _MV_PCIE_MAX_PORT 8
#define _MV_PCIE_IO_SIZE (MV_PCIE_IO_SIZE / _MV_PCIE_MAX_PORT)
#define _MV_PCIE_MEM_SIZE (MV_PCIE_MEM_SIZE / _MV_PCIE_MAX_PORT)
#define _MV_PCIE_IO(n) (MV_PCIE_IO_BASE + ((n) * _MV_PCIE_IO_SIZE))
#define _MV_PCIE_MEM(n) (MV_PCIE_MEM_BASE + ((n) * _MV_PCIE_MEM_SIZE))
#define _MV_PCIE_IO_PHYS(n) (MV_PCIE_IO_PHYS_BASE + ((n) * _MV_PCIE_IO_SIZE))
#define _MV_PCIE_MEM_PHYS(n) (MV_PCIE_MEM_PHYS_BASE + ((n) * _MV_PCIE_MEM_SIZE))
/*
* Note the 'pcib' devices are not declared in the obio_devices[]: due to the
* much more complex configuration schemes allowed, specifically of the
* PCI-Express (multiple lanes width per port configured dynamically etc.) it
* is better and flexible to instantiate the number of PCI bridge devices
* (known in run-time) in the pcib_mbus_identify() method.
*/
struct obio_device obio_devices[] = {
{ "ic", MV_IC_BASE, MV_IC_SIZE,
{ -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "timer", MV_TIMERS_BASE, MV_TIMERS_SIZE,
{ MV_INT_TIMER0, -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "gpio", MV_GPIO_BASE, MV_GPIO_SIZE,
{ MV_INT_GPIO7_0, MV_INT_GPIO15_8,
MV_INT_GPIO23_16, MV_INT_GPIO31_24, -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "uart", MV_UART0_BASE, MV_UART_SIZE,
{ MV_INT_UART0, -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "uart", MV_UART1_BASE, MV_UART_SIZE,
{ MV_INT_UART1, -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "idma", MV_IDMA_BASE, MV_IDMA_SIZE,
{ MV_INT_IDMA_ERR, MV_INT_IDMA0, MV_INT_IDMA1,
MV_INT_IDMA2, MV_INT_IDMA3, -1 },
{ -1 },
CPU_PM_CTRL_IDMA
},
{ "xor", MV_XOR_BASE, MV_XOR_SIZE,
{ MV_INT_XOR0, MV_INT_XOR1,
MV_INT_XOR_ERR, -1 },
{ -1 },
CPU_PM_CTRL_XOR
},
{ "ehci", MV_USB0_BASE, MV_USB_SIZE,
{ MV_INT_USB_ERR, MV_INT_USB0, -1 },
{ -1 },
CPU_PM_CTRL_USB0 | CPU_PM_CTRL_USB1 | CPU_PM_CTRL_USB2
},
{ "ehci", MV_USB1_BASE, MV_USB_SIZE,
{ MV_INT_USB_ERR, MV_INT_USB1, -1 },
{ -1 },
CPU_PM_CTRL_USB0 | CPU_PM_CTRL_USB1 | CPU_PM_CTRL_USB2
},
{ "ehci", MV_USB2_BASE, MV_USB_SIZE,
{ MV_INT_USB_ERR, MV_INT_USB2, -1 },
{ -1 },
CPU_PM_CTRL_USB0 | CPU_PM_CTRL_USB1 | CPU_PM_CTRL_USB2
},
{ "mge", MV_ETH0_BASE, MV_ETH_SIZE,
{ MV_INT_GBERX, MV_INT_GBETX, MV_INT_GBEMISC,
MV_INT_GBESUM, MV_INT_GBE_ERR, -1 },
{ -1 },
CPU_PM_CTRL_GE0
},
{ "mge", MV_ETH1_BASE, MV_ETH_SIZE,
{ MV_INT_GBE1RX, MV_INT_GBE1TX, MV_INT_GBE1MISC,
MV_INT_GBE1SUM, MV_INT_GBE_ERR, -1 },
{ -1 },
CPU_PM_CTRL_GE1
},
{ "twsi", MV_TWSI0_BASE, MV_TWSI_SIZE,
{ -1 }, { -1 },
CPU_PM_CTRL_NONE
},
{ "twsi", MV_TWSI1_BASE, MV_TWSI_SIZE,
{ -1 }, { -1 },
CPU_PM_CTRL_NONE
},
{ "sata", MV_SATAHC_BASE, MV_SATAHC_SIZE,
{ MV_INT_SATA, -1 },
{ -1 },
CPU_PM_CTRL_SATA0 | CPU_PM_CTRL_SATA1
},
{ NULL, 0, 0, { 0 }, { 0 }, 0 }
};
const struct obio_pci mv_pci_info[] = {
{ MV_TYPE_PCIE,
MV_PCIE00_BASE, MV_PCIE_SIZE,
_MV_PCIE_IO(0), _MV_PCIE_IO_SIZE, 4, 0xE0,
_MV_PCIE_MEM(0), _MV_PCIE_MEM_SIZE, 4, 0xE8,
NULL, MV_INT_PEX00 },
{ MV_TYPE_PCIE_AGGR_LANE,
MV_PCIE01_BASE, MV_PCIE_SIZE,
_MV_PCIE_IO(1), _MV_PCIE_IO_SIZE, 4, 0xD0,
_MV_PCIE_MEM(1), _MV_PCIE_MEM_SIZE, 4, 0xD8,
NULL, MV_INT_PEX01 },
#if 0
/*
* XXX Access to devices on this interface (PCIE 0.2) crashes the
* system. Could be a silicon defect as Marvell U-Boot has a 'Do not
* touch' precaution comment...
*/
{ MV_TYPE_PCIE_AGGR_LANE,
MV_PCIE02_BASE, MV_PCIE_SIZE,
_MV_PCIE_IO(2), _MV_PCIE_IO_SIZE(2), 4, 0xB0,
_MV_PCIE_MEM(2), _MV_PCIE_MEM_SIZE(2), 4, 0xB8,
NULL, MV_INT_PEX02 },
#endif
{ MV_TYPE_PCIE_AGGR_LANE,
MV_PCIE03_BASE, MV_PCIE_SIZE,
_MV_PCIE_IO(3), _MV_PCIE_IO_SIZE, 4, 0x70,
_MV_PCIE_MEM(3), _MV_PCIE_MEM_SIZE, 4, 0x78,
NULL, MV_INT_PEX03 },
{ MV_TYPE_PCIE,
MV_PCIE10_BASE, MV_PCIE_SIZE,
_MV_PCIE_IO(4), _MV_PCIE_IO_SIZE, 8, 0xE0,
_MV_PCIE_MEM(4), _MV_PCIE_MEM_SIZE, 8, 0xE8,
NULL, MV_INT_PEX10 },
{ MV_TYPE_PCIE_AGGR_LANE,
MV_PCIE11_BASE, MV_PCIE_SIZE,
_MV_PCIE_IO(5), _MV_PCIE_IO_SIZE, 8, 0xD0,
_MV_PCIE_MEM(5), _MV_PCIE_MEM_SIZE, 8, 0xD8,
NULL, MV_INT_PEX11 },
{ MV_TYPE_PCIE_AGGR_LANE,
MV_PCIE12_BASE, MV_PCIE_SIZE,
_MV_PCIE_IO(6), _MV_PCIE_IO_SIZE, 8, 0xB0,
_MV_PCIE_MEM(6), _MV_PCIE_MEM_SIZE, 8, 0xB8,
NULL, MV_INT_PEX12 },
{ MV_TYPE_PCIE_AGGR_LANE,
MV_PCIE13_BASE, MV_PCIE_SIZE,
_MV_PCIE_IO(7), _MV_PCIE_IO_SIZE, 8, 0x70,
_MV_PCIE_MEM(7), _MV_PCIE_MEM_SIZE, 8, 0x78,
NULL, MV_INT_PEX13 },
{ 0, 0, 0 }
};
struct resource_spec mv_gpio_res[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 0, RF_ACTIVE },
@ -206,57 +52,17 @@ struct resource_spec mv_gpio_res[] = {
{ -1, 0 }
};
struct resource_spec mv_xor_res[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 1, RF_ACTIVE },
{ SYS_RES_IRQ, 2, RF_ACTIVE },
{ -1, 0 }
};
const struct decode_win cpu_win_tbl[] = {
/* Device bus BOOT */
{ 1, 0x2f, MV_DEV_BOOT_PHYS_BASE, MV_DEV_BOOT_SIZE, -1 },
/* Device bus CS0 */
{ 1, 0x3e, MV_DEV_CS0_PHYS_BASE, MV_DEV_CS0_SIZE, -1 },
/* Device bus CS1 */
{ 1, 0x3d, MV_DEV_CS1_PHYS_BASE, MV_DEV_CS1_SIZE, -1 },
/* Device bus CS2 */
{ 1, 0x3b, MV_DEV_CS2_PHYS_BASE, MV_DEV_CS2_SIZE, -1 },
/* CESA */
{ 9, 0x01, MV_CESA_SRAM_PHYS_BASE, MV_CESA_SRAM_SIZE, -1 },
};
const struct decode_win *cpu_wins = cpu_win_tbl;
int cpu_wins_no = sizeof(cpu_win_tbl) / sizeof(struct decode_win);
/*
* Note: the decode windows table for IDMA does not explicitly have DRAM
* entries, which are not statically defined: active DDR banks (== windows)
* are established in run time from actual DDR windows settings. All active
* DDR banks are mapped into IDMA decode windows, so at least one IDMA decode
* window is occupied by the DDR bank; in case when all (MV_WIN_DDR_MAX)
* DDR banks are active, the remaining available IDMA decode windows for other
* targets is only MV_WIN_IDMA_MAX - MV_WIN_DDR_MAX.
*/
const struct decode_win idma_win_tbl[] = {
/* PCIE MEM */
{ 4, 0xE8, _MV_PCIE_MEM_PHYS(0), _MV_PCIE_MEM_SIZE, -1 },
{ 4, 0xD8, _MV_PCIE_MEM_PHYS(1), _MV_PCIE_MEM_SIZE, -1 },
{ 0 },
};
const struct decode_win *idma_wins = idma_win_tbl;
int idma_wins_no = sizeof(idma_win_tbl) / sizeof(struct decode_win);
int idma_wins_no = 0;
const struct decode_win xor_win_tbl[] = {
/* PCIE MEM */
{ 4, 0xE8, _MV_PCIE_MEM_PHYS(0), _MV_PCIE_MEM_SIZE, -1},
{ 4, 0xD8, _MV_PCIE_MEM_PHYS(1), _MV_PCIE_MEM_SIZE, -1},
{ 0 },
};
const struct decode_win *xor_wins = xor_win_tbl;
int xor_wins_no = sizeof(xor_win_tbl) / sizeof(struct decode_win);
int xor_wins_no = 0;
uint32_t
get_tclk(void)
@ -267,7 +73,7 @@ get_tclk(void)
* On Discovery TCLK is can be configured to 166 MHz or 200 MHz.
* Current setting is read from Sample At Reset register.
*/
sar = bus_space_read_4(obio_tag, MV_MPP_BASE, SAMPLE_AT_RESET_HI);
sar = bus_space_read_4(fdtbus_bs_tag, MV_MPP_BASE, SAMPLE_AT_RESET_HI);
sar = (sar & TCLK_MASK) >> TCLK_SHIFT;
switch (sar) {

View File

@ -1,4 +1,3 @@
# $FreeBSD$
arm/mv/discovery/discovery.c standard
arm/mv/discovery/db78xxx.c standard

View File

@ -25,13 +25,10 @@ arm/mv/ic.c standard
arm/mv/mv_machdep.c standard
arm/mv/mv_pci.c optional pci
arm/mv/mv_sata.c optional ata | atamvsata
arm/mv/obio.c standard
arm/mv/timer.c standard
arm/mv/twsi.c optional iicbus
dev/mge/if_mge.c optional mge
dev/mvs/mvs_soc.c optional mvs
dev/uart/uart_bus_mbus.c optional uart
dev/uart/uart_cpu_mv.c optional uart
dev/uart/uart_dev_ns8250.c optional uart
dev/usb/controller/ehci_mbus.c optional ehci
dev/usb/controller/ehci_mv.c optional ehci

View File

@ -44,8 +44,13 @@ __FBSDID("$FreeBSD$");
#include <sys/queue.h>
#include <sys/timetc.h>
#include <machine/bus.h>
#include <machine/fdt.h>
#include <machine/intr.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <arm/mv/mvvar.h>
#include <arm/mv/mvreg.h>
@ -100,12 +105,30 @@ static driver_t mv_gpio_driver = {
static devclass_t mv_gpio_devclass;
DRIVER_MODULE(gpio, mbus, mv_gpio_driver, mv_gpio_devclass, 0, 0);
DRIVER_MODULE(gpio, simplebus, mv_gpio_driver, mv_gpio_devclass, 0, 0);
typedef int (*gpios_phandler_t)(phandle_t, pcell_t *, int);
struct gpio_ctrl_entry {
const char *compat;
gpios_phandler_t handler;
};
int mv_handle_gpios_prop(phandle_t ctrl, pcell_t *gpios, int len);
int gpio_get_config_from_dt(void);
struct gpio_ctrl_entry gpio_controllers[] = {
{ "mrvl,gpio", &mv_handle_gpios_prop },
{ NULL, NULL }
};
static int
mv_gpio_probe(device_t dev)
{
if (!ofw_bus_is_compatible(dev, "mrvl,gpio"))
return (ENXIO);
device_set_desc(dev, "Marvell Integrated GPIO Controller");
return (0);
}
@ -119,8 +142,9 @@ mv_gpio_attach(device_t dev)
sc = (struct mv_gpio_softc *)device_get_softc(dev);
if (mv_gpio_softc != NULL)
if (sc == NULL)
return (ENXIO);
mv_gpio_softc = sc;
/* Get chip id and revision */
@ -178,18 +202,9 @@ mv_gpio_attach(device_t dev)
}
}
/* Setup GPIO lines */
for (i = 0; mv_gpio_config[i].gc_gpio >= 0; i++) {
mv_gpio_configure(mv_gpio_config[i].gc_gpio,
mv_gpio_config[i].gc_flags, ~0u);
if (mv_gpio_config[i].gc_output < 0)
mv_gpio_out_en(mv_gpio_config[i].gc_gpio, 0);
else
mv_gpio_out(mv_gpio_config[i].gc_gpio,
mv_gpio_config[i].gc_output, 1);
}
/*
* GPIO lines setup is already done at this stage (see mv_machdep.c).
*/
return (0);
}
@ -268,7 +283,7 @@ mv_gpio_intr_mask(int pin)
if (pin >= mv_gpio_softc->pin_num)
return;
if (gpio_setup[pin] & MV_GPIO_EDGE)
if (gpio_setup[pin] & MV_GPIO_IN_IRQ_EDGE)
mv_gpio_edge(pin, 0);
else
mv_gpio_level(pin, 0);
@ -281,7 +296,7 @@ mv_gpio_intr_unmask(int pin)
if (pin >= mv_gpio_softc->pin_num)
return;
if (gpio_setup[pin] & MV_GPIO_EDGE)
if (gpio_setup[pin] & MV_GPIO_IN_IRQ_EDGE)
mv_gpio_edge(pin, 1);
else
mv_gpio_level(pin, 1);
@ -299,24 +314,23 @@ mv_gpio_intr_handler(int pin)
intr_event_handle(event, NULL);
}
int
mv_gpio_configure(uint32_t pin, uint32_t flags, uint32_t mask)
static int
mv_gpio_configure(uint32_t pin, uint32_t flags)
{
if (pin >= mv_gpio_softc->pin_num)
return (EINVAL);
if (mask & MV_GPIO_BLINK)
mv_gpio_blink(pin, flags & MV_GPIO_BLINK);
if (mask & MV_GPIO_POLAR_LOW)
mv_gpio_polarity(pin, flags & MV_GPIO_POLAR_LOW);
if (mask & MV_GPIO_EDGE)
mv_gpio_edge(pin, flags & MV_GPIO_EDGE);
if (mask & MV_GPIO_LEVEL)
mv_gpio_level(pin, flags & MV_GPIO_LEVEL);
if (flags & MV_GPIO_OUT_BLINK)
mv_gpio_blink(pin, 1);
if (flags & MV_GPIO_IN_POL_LOW)
mv_gpio_polarity(pin, 1);
if (flags & MV_GPIO_IN_IRQ_EDGE)
mv_gpio_edge(pin, 1);
if (flags & MV_GPIO_IN_IRQ_LEVEL)
mv_gpio_level(pin, 1);
gpio_setup[pin] &= ~(mask);
gpio_setup[pin] |= (flags & mask);
gpio_setup[pin] = flags;
return (0);
}
@ -527,3 +541,142 @@ mv_gpio_value_set(uint32_t pin, uint8_t val)
else
mv_gpio_reg_clear(reg, pin);
}
int
mv_handle_gpios_prop(phandle_t ctrl, pcell_t *gpios, int len)
{
pcell_t gpio_cells, pincnt;
int inc, t, tuples, tuple_size;
int dir, flags, pin;
u_long gpio_ctrl, size;
struct mv_gpio_softc sc;
pincnt = 0;
if (OF_getproplen(ctrl, "gpio-controller") <= 0)
/* Node is not a GPIO controller. */
return (ENXIO);
if (OF_getprop(ctrl, "#gpio-cells", &gpio_cells, sizeof(pcell_t)) < 0)
return (ENXIO);
gpio_cells = fdt32_to_cpu(gpio_cells);
if (gpio_cells != 3)
return (ENXIO);
tuple_size = gpio_cells * sizeof(pcell_t) + sizeof(phandle_t);
tuples = len / tuple_size;
if (fdt_regsize(ctrl, &gpio_ctrl, &size))
return (ENXIO);
/*
* Since to set up GPIO we use the same functions as GPIO driver, and
* mv_gpio_softc is NULL at this early stage, we need to create a fake
* softc and set mv_gpio_softc pointer to that newly created object.
* After successful GPIO setup, the [shared] pointer will be set back
* to NULL.
*/
mv_gpio_softc = &sc;
sc.bst = fdtbus_bs_tag;
gpio_ctrl += fdt_immr_va;
if (bus_space_map(sc.bst, gpio_ctrl, size, 0, &sc.bsh) != 0)
return (ENXIO);
if (OF_getprop(ctrl, "pin-count", &pincnt, sizeof(pcell_t)) < 0)
return (ENXIO);
sc.pin_num = fdt32_to_cpu(pincnt);
/*
* Skip controller reference, since controller's phandle is given
* explicitly (in a function argument).
*/
inc = sizeof(ihandle_t) / sizeof(pcell_t);
gpios += inc;
for (t = 0; t < tuples; t++) {
pin = fdt32_to_cpu(gpios[0]);
dir = fdt32_to_cpu(gpios[1]);
flags = fdt32_to_cpu(gpios[2]);
mv_gpio_configure(pin, flags);
if (dir == 1)
/* Input. */
mv_gpio_out_en(pin, 0);
else {
/* Output. */
if (flags & MV_GPIO_OUT_OPEN_DRAIN)
mv_gpio_out(pin, 0, 1);
if (flags & MV_GPIO_OUT_OPEN_SRC)
mv_gpio_out(pin, 1, 1);
}
gpios += gpio_cells + inc;
}
/* Reset pointer. */
mv_gpio_softc = NULL;
return (0);
}
#define MAX_PINS_PER_NODE 5
#define GPIOS_PROP_CELLS 4
int
platform_gpio_init(void)
{
phandle_t child, parent, root, ctrl;
ihandle_t ctrl_ihandle;
pcell_t gpios[MAX_PINS_PER_NODE * GPIOS_PROP_CELLS];
struct gpio_ctrl_entry *e;
int len, rv;
root = OF_finddevice("/");
len = 0;
parent = root;
/* Traverse through entire tree to find nodes with 'gpios' prop */
for (child = OF_child(parent); child != 0; child = OF_peer(child)) {
/* Find a 'leaf'. Start the search from this node. */
while (OF_child(child)) {
parent = child;
child = OF_child(child);
}
if ((len = OF_getproplen(child, "gpios")) > 0) {
if (len > sizeof(gpios))
return (ENXIO);
/* Get 'gpios' property. */
OF_getprop(child, "gpios", &gpios, len);
e = (struct gpio_ctrl_entry *)&gpio_controllers;
/* Find and call a handler. */
for (; e->compat; e++) {
/*
* First cell of 'gpios' property should
* contain a ref. to a node defining GPIO
* controller.
*/
ctrl_ihandle = (ihandle_t)gpios[0];
ctrl_ihandle = fdt32_to_cpu(ctrl_ihandle);
ctrl = OF_instance_to_package(ctrl_ihandle);
if (fdt_is_compatible(ctrl, e->compat))
/* Call a handler. */
if ((rv = e->handler(ctrl,
(pcell_t *)&gpios, len)))
return (rv);
}
}
if (OF_peer(child) == 0) {
/* No more siblings. */
child = parent;
parent = OF_parent(child);
}
}
return (0);
}

View File

@ -40,6 +40,9 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/intr.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <arm/mv/mvreg.h>
#include <arm/mv/mvvar.h>
@ -76,6 +79,9 @@ static int
mv_ic_probe(device_t dev)
{
if (!ofw_bus_is_compatible(dev, "mrvl,pic"))
return (ENXIO);
device_set_desc(dev, "Marvell Integrated Interrupt Controller");
return (0);
}
@ -134,7 +140,7 @@ static driver_t mv_ic_driver = {
static devclass_t mv_ic_devclass;
DRIVER_MODULE(ic, mbus, mv_ic_driver, mv_ic_devclass, 0, 0);
DRIVER_MODULE(ic, simplebus, mv_ic_driver, mv_ic_devclass, 0, 0);
int
arm_get_next_irq(int last __unused)

View File

@ -1,157 +0,0 @@
/*-
* Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
* All rights reserved.
*
* Developed by Semihalf.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of MARVELL nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/bus.h>
#include <machine/pte.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
#include <arm/mv/mvreg.h>
#include <arm/mv/mvvar.h>
#include <arm/mv/mvwin.h>
/*
* Virtual address space layout:
* -----------------------------
* 0x0000_0000 - 0xbfff_ffff : user process
*
* 0xc040_0000 - virtual_avail : kernel reserved (text, data, page tables
* : structures, ARM stacks etc.)
* virtual_avail - 0xefff_ffff : KVA (virtual_avail is typically < 0xc0a0_0000)
* 0xf000_0000 - 0xf0ff_ffff : no-cache allocation area (16MB)
* 0xf100_0000 - 0xf10f_ffff : SoC integrated devices registers range (1MB)
* 0xf110_0000 - 0xf11f_ffff : PCI-Express I/O space (1MB)
* 0xf120_0000 - 0xf12f_ffff : unused (1MB)
* 0xf130_0000 - 0xf52f_ffff : PCI-Express memory space (64MB)
* 0xf930_0000 - 0xfffe_ffff : unused (~172MB)
* 0xffff_0000 - 0xffff_0fff : 'high' vectors page (4KB)
* 0xffff_1000 - 0xffff_1fff : ARM_TP_ADDRESS/RAS page (4KB)
* 0xffff_2000 - 0xffff_ffff : unused (~55KB)
*/
/* Static device mappings. */
const struct pmap_devmap pmap_devmap[] = {
/*
* Map the on-board devices VA == PA so that we can access them
* with the MMU on or off.
*/
{ /* SoC integrated peripherals registers range */
MV_BASE,
MV_PHYS_BASE,
MV_SIZE,
VM_PROT_READ | VM_PROT_WRITE,
PTE_NOCACHE,
},
{ /* PCIE I/O */
MV_PCIE_IO_BASE,
MV_PCIE_IO_PHYS_BASE,
MV_PCIE_IO_SIZE,
VM_PROT_READ | VM_PROT_WRITE,
PTE_NOCACHE,
},
{ /* PCIE Memory */
MV_PCIE_MEM_BASE,
MV_PCIE_MEM_PHYS_BASE,
MV_PCIE_MEM_SIZE,
VM_PROT_READ | VM_PROT_WRITE,
PTE_NOCACHE,
},
{ 0, 0, 0, 0, 0, }
};
const struct gpio_config mv_gpio_config[] = {
{ -1, -1, -1 }
};
void
platform_mpp_init(void)
{
/*
* MPP configuration for DB-88F6281-BP and DB-88F6281-BP-A
*
* MPP[0]: NF_IO[2]
* MPP[1]: NF_IO[3]
* MPP[2]: NF_IO[4]
* MPP[3]: NF_IO[5]
* MPP[4]: NF_IO[6]
* MPP[5]: NF_IO[7]
* MPP[6]: SYSRST_OUTn
* MPP[7]: SPI_SCn
* MPP[8]: TW_SDA
* MPP[9]: TW_SCK
* MPP[10]: UA0_TXD
* MPP[11]: UA0_RXD
* MPP[12]: SD_CLK
* MPP[13]: SD_CMD
* MPP[14]: SD_D[0]
* MPP[15]: SD_D[1]
* MPP[16]: SD_D[2]
* MPP[17]: SD_D[3]
* MPP[18]: NF_IO[0]
* MPP[19]: NF_IO[1]
* MPP[20]: SATA1_AC
* MPP[21]: SATA0_AC
*
* Others: GPIO
*/
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL0, 0x21111111);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL1, 0x11113311);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL2, 0x00551111);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL3, 0x00000000);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL4, 0x00000000);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL5, 0x00000000);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL6, 0x00000000);
}
static void
platform_identify(void *dummy)
{
soc_identify();
/*
* XXX Board identification e.g. read out from FPGA or similar should
* go here
*/
}
SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify, NULL);

View File

@ -1,4 +0,0 @@
# $FreeBSD$
include "arm/mv/kirkwood/files.kirkwood"
arm/mv/kirkwood/db88f6xxx.c standard

View File

@ -42,82 +42,6 @@ __FBSDID("$FreeBSD$");
#include <arm/mv/mvvar.h>
#include <arm/mv/mvwin.h>
struct obio_device obio_devices[] = {
{ "ic", MV_IC_BASE, MV_IC_SIZE,
{ -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "timer", MV_TIMERS_BASE, MV_TIMERS_SIZE,
{ MV_INT_BRIDGE, -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "rtc", MV_RTC_BASE, MV_RTC_SIZE,
{ -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "gpio", MV_GPIO_BASE, MV_GPIO_SIZE,
{ MV_INT_GPIO7_0, MV_INT_GPIO15_8,
MV_INT_GPIO23_16, MV_INT_GPIO31_24,
MV_INT_GPIOHI7_0, MV_INT_GPIOHI15_8,
MV_INT_GPIOHI23_16, -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "uart", MV_UART0_BASE, MV_UART_SIZE,
{ MV_INT_UART0, -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "uart", MV_UART1_BASE, MV_UART_SIZE,
{ MV_INT_UART1, -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "xor", MV_XOR_BASE, MV_XOR_SIZE,
{ MV_INT_XOR0_CHAN0, MV_INT_XOR0_CHAN1,
MV_INT_XOR1_CHAN0, MV_INT_XOR1_CHAN1,
MV_INT_XOR0_ERR, MV_INT_XOR1_ERR,
-1 },
{ -1 },
CPU_PM_CTRL_XOR0 | CPU_PM_CTRL_XOR1
},
{ "ehci", MV_USB0_BASE, MV_USB_SIZE,
{ MV_INT_USB_BERR, MV_INT_USB_CI, -1 },
{ -1 },
CPU_PM_CTRL_USB0
},
{ "mge", MV_ETH0_BASE, MV_ETH_SIZE,
{ MV_INT_GBERX, MV_INT_GBETX, MV_INT_GBEMISC,
MV_INT_GBESUM, MV_INT_GBEERR, -1 },
{ -1 },
CPU_PM_CTRL_GE0
},
{ "twsi", MV_TWSI0_BASE, MV_TWSI_SIZE,
{ -1 }, { -1 },
CPU_PM_CTRL_NONE
},
{ "sata", MV_SATAHC_BASE, MV_SATAHC_SIZE,
{ MV_INT_SATA, -1 },
{ -1 },
CPU_PM_CTRL_SATA0 | CPU_PM_CTRL_SATA1
},
{ NULL, 0, 0, { 0 }, { 0 }, 0 }
};
const struct obio_pci mv_pci_info[] = {
{ MV_TYPE_PCIE,
MV_PCIE_BASE, MV_PCIE_SIZE,
MV_PCIE_IO_BASE, MV_PCIE_IO_SIZE, 4, 0xE0,
MV_PCIE_MEM_BASE, MV_PCIE_MEM_SIZE, 4, 0xE8,
NULL, MV_INT_PEX0
},
{ 0, 0, 0 }
};
struct resource_spec mv_gpio_res[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 0, RF_ACTIVE },
@ -130,43 +54,11 @@ struct resource_spec mv_gpio_res[] = {
{ -1, 0 }
};
struct resource_spec mv_xor_res[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 1, RF_ACTIVE },
{ SYS_RES_IRQ, 2, RF_ACTIVE },
{ SYS_RES_IRQ, 3, RF_ACTIVE },
{ SYS_RES_IRQ, 4, RF_ACTIVE },
{ SYS_RES_IRQ, 5, RF_ACTIVE },
{ -1, 0 }
};
const struct decode_win cpu_win_tbl[] = {
/* Device bus BOOT */
{ 1, 0x0f, MV_DEV_BOOT_PHYS_BASE, MV_DEV_BOOT_SIZE, -1 },
/* Device bus CS0 */
{ 1, 0x1e, MV_DEV_CS0_PHYS_BASE, MV_DEV_CS0_SIZE, -1 },
/* Device bus CS1 */
{ 1, 0x1d, MV_DEV_CS1_PHYS_BASE, MV_DEV_CS1_SIZE, -1 },
/* Device bus CS2 */
{ 1, 0x1b, MV_DEV_CS2_PHYS_BASE, MV_DEV_CS2_SIZE, -1 },
/* CESA */
{ 3, 0x00, MV_CESA_SRAM_PHYS_BASE, MV_CESA_SRAM_SIZE, -1 },
};
const struct decode_win *cpu_wins = cpu_win_tbl;
int cpu_wins_no = sizeof(cpu_win_tbl) / sizeof(struct decode_win);
const struct decode_win xor_win_tbl[] = {
/* PCIE MEM */
{ 4, 0xE8, MV_PCIE_MEM_PHYS_BASE, MV_PCIE_MEM_SIZE, -1 },
{ 0 },
};
const struct decode_win *xor_wins = xor_win_tbl;
int xor_wins_no = sizeof(xor_win_tbl) / sizeof(struct decode_win);
int xor_wins_no = 0;
uint32_t
get_tclk(void)

View File

@ -1,8 +1,10 @@
/*-
* Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
* Copyright (C) 2009 Semihalf
* Copyright (c) 2010 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Semihalf under sponsorship from
* the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -11,14 +13,11 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of MARVELL nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@ -31,122 +30,15 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/fdt.h>
#include <machine/bus.h>
#include <machine/pte.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
#include <arm/mv/mvreg.h>
#include <arm/mv/mvvar.h>
#include <arm/mv/mvwin.h>
/*
* Virtual address space layout:
* -----------------------------
* 0x0000_0000 - 0x7FFF_FFFF : User Process (2 GB)
* 0x8000_0000 - 0xBBFF_FFFF : Unused (960 MB)
* 0xBC00_0000 - 0xBDFF_FFFF : Device Bus: CS1 (32 MB)
* 0xBE00_0000 - 0xBECF_FFFF : Unused (13 MB)
* 0xBED0_0000 - 0xBEDF_FFFF : Device Bus: CS2 (1 MB)
* 0xBEE0_0000 - 0xBEEF_FFFF : Device Bus: CS0 (1 MB)
* 0xBEF0_0000 - 0xBEFF_FFFF : Device Bus: BOOT (1 MB)
* 0xBF00_0000 - 0xBFFF_FFFF : Unused (16 MB)
* 0xC000_0000 - virtual_avail : Kernel Reserved (text, data, page tables,
* : stack etc.)
* virtual-avail - 0xEFFF_FFFF : KVA (virtual_avail is typically < 0xc0a0_0000)
* 0xF000_0000 - 0xF0FF_FFFF : No-Cache allocation area (16 MB)
* 0xF100_0000 - 0xF10F_FFFF : SoC Integrated devices registers range (1 MB)
* 0xF110_0000 - 0xF11F_FFFF : CESA SRAM (1 MB)
* 0xF120_0000 - 0xFFFE_FFFF : Unused (237 MB + 960 kB)
* 0xFFFF_0000 - 0xFFFF_0FFF : 'High' vectors page (4 kB)
* 0xFFFF_1000 - 0xFFFF_1FFF : ARM_TP_ADDRESS/RAS page (4 kB)
* 0xFFFF_2000 - 0xFFFF_FFFF : Unused (56 kB)
*/
/* Static device mappings. */
const struct pmap_devmap pmap_devmap[] = {
/*
* Map the on-board devices VA == PA so that we can access them
* with the MMU on or off.
*/
{ /* SoC integrated peripherals registers range */
MV_BASE,
MV_PHYS_BASE,
MV_SIZE,
VM_PROT_READ | VM_PROT_WRITE,
PTE_NOCACHE,
},
{ /* CESA SRAM */
MV_CESA_SRAM_BASE,
MV_CESA_SRAM_PHYS_BASE,
MV_CESA_SRAM_SIZE,
VM_PROT_READ | VM_PROT_WRITE,
PTE_NOCACHE,
},
{ 0, 0, 0, 0, 0, }
};
const struct gpio_config mv_gpio_config[] = {
{ -1, -1, -1 }
};
void
platform_mpp_init(void)
int
fdt_pci_devmap(phandle_t node, struct pmap_devmap *devmap, vm_offset_t io_va,
vm_offset_t mem_va)
{
/*
* MPP configuration for Sheeva Plug
*
* MPP[0]: NF_IO[2]
* MPP[1]: NF_IO[3]
* MPP[2]: NF_IO[4]
* MPP[3]: NF_IO[5]
* MPP[4]: NF_IO[6]
* MPP[5]: NF_IO[7]
* MPP[6]: SYSRST_OUTn
* MPP[8]: UA0_RTS
* MPP[9]: UA0_CTS
* MPP[10]: UA0_TXD
* MPP[11]: UA0_RXD
* MPP[12]: SD_CLK
* MPP[13]: SD_CMD
* MPP[14]: SD_D[0]
* MPP[15]: SD_D[1]
* MPP[16]: SD_D[2]
* MPP[17]: SD_D[3]
* MPP[18]: NF_IO[0]
* MPP[19]: NF_IO[1]
* MPP[29]: TSMP[9]
*
* Others: GPIO
*/
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL0, 0x01111111);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL1, 0x11113322);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL2, 0x00001111);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL3, 0x00100000);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL4, 0x00000000);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL5, 0x00000000);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL6, 0x00000000);
return (0);
}
static void
platform_identify(void *dummy)
{
soc_identify();
/*
* XXX Board identification e.g. read out from FPGA or similar should
* go here
*/
}
SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify, NULL);

View File

@ -2,7 +2,6 @@
include "../mv/std.mv"
include "../mv/kirkwood/std.kirkwood"
files "../mv/kirkwood/files.db88f6xxx"
files "../mv/kirkwood/files.kirkwood"
options PHYSMEM_SIZE=0x20000000

View File

@ -5,4 +5,3 @@ include "../mv/kirkwood/std.kirkwood"
files "../mv/kirkwood/files.sheevaplug"
options PHYSMEM_SIZE=0x20000000
options MII_ADDR_BASE=0

View File

@ -37,6 +37,7 @@
#include "opt_msgbuf.h"
#include "opt_ddb.h"
#include "opt_platform.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -65,6 +66,10 @@ __FBSDID("$FreeBSD$");
#include <sys/msgbuf.h>
#include <machine/reg.h>
#include <machine/cpu.h>
#include <machine/fdt.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#include <vm/vm.h>
#include <vm/pmap.h>
@ -82,11 +87,14 @@ __FBSDID("$FreeBSD$");
#include <machine/armreg.h>
#include <machine/bus.h>
#include <sys/reboot.h>
#include <machine/bootinfo.h>
#include <arm/mv/mvreg.h> /* XXX */
#include <arm/mv/mvvar.h> /* XXX eventually this should be eliminated */
#include <arm/mv/mvwin.h>
#define DEBUG
#undef DEBUG
#ifdef DEBUG
#define debugf(fmt, args...) printf(fmt, ##args)
#else
@ -105,9 +113,6 @@ __FBSDID("$FreeBSD$");
#define ABT_STACK_SIZE 1
#define UND_STACK_SIZE 1
/* Maximum number of memory regions */
#define MEM_REGIONS 8
extern unsigned char kernbase[];
extern unsigned char _etext[];
extern unsigned char _edata[];
@ -118,13 +123,10 @@ extern u_int data_abort_handler_address;
extern u_int prefetch_abort_handler_address;
extern u_int undefined_handler_address;
extern const struct pmap_devmap *pmap_devmap_bootstrap_table;
extern vm_offset_t pmap_bootstrap_lastaddr;
struct pv_addr kernel_pt_table[KERNEL_PT_MAX];
extern int *end;
struct pv_addr kernel_pt_table[KERNEL_PT_MAX];
struct pcpu __pcpu;
struct pcpu *pcpup = &__pcpu;
@ -145,21 +147,15 @@ struct pv_addr kernelstack;
static struct trapframe proc0_tf;
struct mem_region {
vm_offset_t mr_start;
vm_size_t mr_size;
};
static struct mem_region availmem_regions[MEM_REGIONS];
static struct mem_region availmem_regions[FDT_MEM_REGIONS];
static int availmem_regions_sz;
struct bootinfo *bootinfo;
static void print_kenv(void);
static void print_kernel_section_addr(void);
static void print_bootinfo(void);
static void physmap_init(int);
static int platform_devmap_init(void);
static int platform_mpp_init(void);
static char *
kenv_next(char *cp)
@ -193,40 +189,6 @@ print_kenv(void)
debugf(" %x %s\n", (uint32_t)cp, cp);
}
static void
print_bootinfo(void)
{
struct bi_mem_region *mr;
struct bi_eth_addr *eth;
int i, j;
debugf("bootinfo:\n");
if (bootinfo == NULL) {
debugf(" no bootinfo, null ptr\n");
return;
}
debugf(" version = 0x%08x\n", bootinfo->bi_version);
debugf(" ccsrbar = 0x%08x\n", bootinfo->bi_bar_base);
debugf(" cpu_clk = 0x%08x\n", bootinfo->bi_cpu_clk);
debugf(" bus_clk = 0x%08x\n", bootinfo->bi_bus_clk);
debugf(" mem regions:\n");
mr = (struct bi_mem_region *)bootinfo->bi_data;
for (i = 0; i < bootinfo->bi_mem_reg_no; i++, mr++)
debugf(" #%d, base = 0x%08x, size = 0x%08x\n", i,
mr->mem_base, mr->mem_size);
debugf(" eth addresses:\n");
eth = (struct bi_eth_addr *)mr;
for (i = 0; i < bootinfo->bi_eth_addr_no; i++, eth++) {
debugf(" #%d, addr = ", i);
for (j = 0; j < 6; j++)
debugf("%02x ", eth->mac_addr[j]);
debugf("\n");
}
}
static void
print_kernel_section_addr(void)
{
@ -239,13 +201,6 @@ print_kernel_section_addr(void)
debugf(" _end = 0x%08x\n", (uint32_t)_end);
}
struct bi_mem_region *
bootinfo_mr(void)
{
return ((struct bi_mem_region *)bootinfo->bi_data);
}
static void
physmap_init(int hardcoded)
{
@ -361,9 +316,8 @@ initarm(void *mdp, void *unused __unused)
{
struct pv_addr kernel_l1pt;
struct pv_addr dpcpu;
vm_offset_t freemempos, l2_start, lastaddr;
vm_offset_t dtbp, freemempos, l2_start, lastaddr;
uint32_t memsize, l2size;
struct bi_mem_region *mr;
void *kmdp;
u_int l1pagetable;
int i = 0, j = 0;
@ -371,6 +325,7 @@ initarm(void *mdp, void *unused __unused)
kmdp = NULL;
lastaddr = 0;
memsize = 0;
dtbp = (vm_offset_t)NULL;
set_cpufuncs();
@ -387,24 +342,13 @@ initarm(void *mdp, void *unused __unused)
preload_metadata = mdp;
kmdp = preload_search_by_type("elf kernel");
if (kmdp != NULL) {
bootinfo = (struct bootinfo *)preload_search_info(kmdp,
MODINFO_METADATA|MODINFOMD_BOOTINFO);
boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
lastaddr = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t);
dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t);
lastaddr = MD_FETCH(kmdp, MODINFOMD_KERNEND,
vm_offset_t);
}
/* Initialize memory regions table */
mr = bootinfo_mr();
for (i = 0; i < bootinfo->bi_mem_reg_no; i++, mr++) {
if (i == MEM_REGIONS)
break;
availmem_regions[i].mr_start = mr->mem_base;
availmem_regions[i].mr_size = mr->mem_size;
memsize += mr->mem_size;
}
availmem_regions_sz = i;
} else {
/* Fall back to hardcoded metadata. */
lastaddr = fake_preload_metadata();
@ -416,16 +360,31 @@ initarm(void *mdp, void *unused __unused)
memsize = PHYSMEM_SIZE;
}
#if defined(FDT_DTB_STATIC)
/*
* If memsize is invalid, we can neither proceed nor panic (too
* early for console output).
* In case the device tree blob was not retrieved (from metadata) try
* to use the statically embedded one.
*/
if (memsize == 0)
if (dtbp == (vm_offset_t)NULL)
dtbp = (vm_offset_t)&fdt_static_dtb;
#endif
if (OF_install(OFW_FDT, 0) == FALSE)
while (1);
if (OF_init((void *)dtbp) != 0)
while (1);
/* Grab physical memory regions information from device tree. */
if (fdt_get_mem_regions(availmem_regions, &availmem_regions_sz,
&memsize) != 0)
while(1);
if (fdt_immr_addr() != 0)
while (1);
/* Platform-specific initialisation */
pmap_bootstrap_lastaddr = MV_BASE - ARM_NOCACHE_KVA_SIZE;
pmap_devmap_bootstrap_table = &pmap_devmap[0];
pmap_bootstrap_lastaddr = fdt_immr_va - ARM_NOCACHE_KVA_SIZE;
pcpu_init(pcpup, 0, sizeof(struct pcpu));
PCPU_SET(curthread, &thread0);
@ -540,27 +499,46 @@ initarm(void *mdp, void *unused __unused)
pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
/* Map pmap_devmap[] entries */
if (platform_devmap_init() != 0)
while (1);
pmap_devmap_bootstrap(l1pagetable, pmap_devmap_bootstrap_table);
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) |
DOMAIN_CLIENT);
setttb(kernel_l1pt.pv_pa);
cpu_tlb_flushID();
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2));
/*
* Only after the SOC registers block is mapped we can perform device
* tree fixups, as they may attempt to read parameters from hardware.
*/
OF_interpret("perform-fixup", 0);
/*
* Re-initialise MPP. It is important to call this prior to using
* console as the physical connection can be routed via MPP.
*/
if (platform_mpp_init() != 0)
while (1);
/*
* Initialize GPIO as early as possible.
*/
if (platform_gpio_init() != 0)
while (1);
cninit();
physmem = memsize / PAGE_SIZE;
debugf("initarm: console initialized\n");
debugf(" arg1 mdp = 0x%08x\n", (uint32_t)mdp);
debugf(" boothowto = 0x%08x\n", boothowto);
print_bootinfo();
printf(" dtbp = 0x%08x\n", (uint32_t)dtbp);
print_kernel_section_addr();
print_kenv();
/*
* Re-initialise MPP
*/
platform_mpp_init();
/*
* Re-initialise decode windows
*/
@ -637,6 +615,217 @@ initarm(void *mdp, void *unused __unused)
sizeof(struct pcb)));
}
#define MPP_PIN_MAX 50
#define MPP_PIN_CELLS 2
#define MPP_PINS_PER_REG 8
#define MPP_SEL(pin,func) (((func) & 0xf) << \
(((pin) % MPP_PINS_PER_REG) * 4))
static int
platform_mpp_init(void)
{
pcell_t pinmap[MPP_PIN_MAX * MPP_PIN_CELLS];
int mpp[MPP_PIN_MAX];
uint32_t ctrl_val, ctrl_offset;
pcell_t reg[4];
u_long start, size;
phandle_t node;
pcell_t pin_cells, *pinmap_ptr, pin_count;
ssize_t len;
int par_addr_cells, par_size_cells;
int tuple_size, tuples, rv, pins, i, j;
int mpp_pin, mpp_function;
/*
* Try to access the MPP node directly i.e. through /aliases/mpp.
*/
if ((node = OF_finddevice("mpp")) != 0)
if (fdt_is_compatible(node, "mrvl,mpp"))
goto moveon;
/*
* Find the node the long way.
*/
if ((node = OF_finddevice("/")) == 0)
return (ENXIO);
if ((node = fdt_find_compatible(node, "simple-bus", 0)) == 0)
return (ENXIO);
if ((node = fdt_find_compatible(node, "mrvl,mpp", 0)) == 0)
return (ENXIO);
moveon:
/*
* Process 'reg' prop.
*/
if ((rv = fdt_addrsize_cells(OF_parent(node), &par_addr_cells,
&par_size_cells)) != 0)
return(ENXIO);
tuple_size = sizeof(pcell_t) * (par_addr_cells + par_size_cells);
len = OF_getprop(node, "reg", reg, sizeof(reg));
tuples = len / tuple_size;
if (tuple_size <= 0)
return (EINVAL);
/*
* Get address/size. XXX we assume only the first 'reg' tuple is used.
*/
rv = fdt_data_to_res(reg, par_addr_cells, par_size_cells,
&start, &size);
if (rv != 0)
return (rv);
start += fdt_immr_va;
/*
* Process 'pin-count' and 'pin-map' props.
*/
if (OF_getprop(node, "pin-count", &pin_count, sizeof(pin_count)) <= 0)
return (ENXIO);
pin_count = fdt32_to_cpu(pin_count);
if (pin_count > MPP_PIN_MAX)
return (ERANGE);
if (OF_getprop(node, "#pin-cells", &pin_cells, sizeof(pin_cells)) <= 0)
pin_cells = MPP_PIN_CELLS;
pin_cells = fdt32_to_cpu(pin_cells);
if (pin_cells > MPP_PIN_CELLS)
return (ERANGE);
tuple_size = sizeof(pcell_t) * pin_cells;
bzero(pinmap, sizeof(pinmap));
len = OF_getprop(node, "pin-map", pinmap, sizeof(pinmap));
if (len <= 0)
return (ERANGE);
if (len % tuple_size)
return (ERANGE);
pins = len / tuple_size;
if (pins > pin_count)
return (ERANGE);
/*
* Fill out a "mpp[pin] => function" table. All pins unspecified in
* the 'pin-map' property are defaulted to 0 function i.e. GPIO.
*/
bzero(mpp, sizeof(mpp));
pinmap_ptr = pinmap;
for (i = 0; i < pins; i++) {
mpp_pin = fdt32_to_cpu(*pinmap_ptr);
mpp_function = fdt32_to_cpu(*(pinmap_ptr + 1));
mpp[mpp_pin] = mpp_function;
pinmap_ptr += pin_cells;
}
/*
* Prepare and program MPP control register values.
*/
ctrl_offset = 0;
for (i = 0; i < pin_count;) {
ctrl_val = 0;
for (j = 0; j < MPP_PINS_PER_REG; j++) {
if (i + j == pin_count - 1)
break;
ctrl_val |= MPP_SEL(i + j, mpp[i + j]);
}
i += MPP_PINS_PER_REG;
bus_space_write_4(fdtbus_bs_tag, start, ctrl_offset,
ctrl_val);
#if defined(SOC_MV_ORION)
/*
* Third MPP reg on Orion SoC is placed
* non-linearly (with different offset).
*/
if (i == (2 * MPP_PINS_PER_REG))
ctrl_offset = 0x50;
else
#endif
ctrl_offset += 4;
}
return (0);
}
#define FDT_DEVMAP_MAX (1 + 2 + 1 + 1)
static struct pmap_devmap fdt_devmap[FDT_DEVMAP_MAX] = {
{ 0, 0, 0, 0, 0, }
};
/*
* Construct pmap_devmap[] with DT-derived config data.
*/
static int
platform_devmap_init(void)
{
phandle_t root, child;
u_long base, size;
int i;
/*
* IMMR range.
*/
i = 0;
fdt_devmap[i].pd_va = fdt_immr_va;
fdt_devmap[i].pd_pa = fdt_immr_pa;
fdt_devmap[i].pd_size = fdt_immr_size;
fdt_devmap[i].pd_prot = VM_PROT_READ | VM_PROT_WRITE;
fdt_devmap[i].pd_cache = PTE_NOCACHE;
i++;
/*
* PCI range(s).
*/
if ((root = OF_finddevice("/")) == 0)
return (ENXIO);
for (child = OF_child(root); child != 0; child = OF_peer(child))
if (fdt_is_type(child, "pci")) {
/*
* Check space: each PCI node will consume 2 devmap
* entries.
*/
if (i + 1 >= FDT_DEVMAP_MAX) {
return (ENOMEM);
break;
}
/*
* XXX this should account for PCI and multiple ranges
* of a given kind.
*/
if (fdt_pci_devmap(child, &fdt_devmap[i],
MV_PCIE_IO_BASE, MV_PCIE_MEM_BASE) != 0)
return (ENXIO);
i += 2;
}
/*
* CESA SRAM range.
*/
if ((child = OF_finddevice("sram")) != 0)
if (fdt_is_compatible(child, "mrvl,cesa-sram"))
goto moveon;
if ((child = fdt_find_compatible(root, "mrvl,cesa-sram", 0)) == 0)
/* No CESA SRAM node. */
goto out;
moveon:
if (i >= FDT_DEVMAP_MAX)
return (ENOMEM);
if (fdt_regsize(child, &base, &size) != 0)
return (EINVAL);
fdt_devmap[i].pd_va = MV_CESA_SRAM_BASE; /* XXX */
fdt_devmap[i].pd_pa = base;
fdt_devmap[i].pd_size = size;
fdt_devmap[i].pd_prot = VM_PROT_READ | VM_PROT_WRITE;
fdt_devmap[i].pd_cache = PTE_NOCACHE;
out:
pmap_devmap_bootstrap_table = &fdt_devmap[0];
return (0);
}
struct arm32_dma_range *
bus_dma_get_range(void)
{

File diff suppressed because it is too large Load Diff

View File

@ -48,6 +48,8 @@ __FBSDID("$FreeBSD$");
#include <sys/ata.h>
#include <dev/ata/ata-all.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include "ata_if.h"
@ -173,7 +175,7 @@ static driver_t sata_driver = {
devclass_t sata_devclass;
DRIVER_MODULE(sata, mbus, sata_driver, sata_devclass, 0, 0);
DRIVER_MODULE(sata, simplebus, sata_driver, sata_devclass, 0, 0);
MODULE_VERSION(sata, 1);
MODULE_DEPEND(sata, ata, 1, 1, 1);
@ -183,13 +185,12 @@ sata_probe(device_t dev)
struct sata_softc *sc;
uint32_t d, r;
if (!ofw_bus_is_compatible(dev, "mrvl,sata"))
return (ENXIO);
soc_id(&d, &r);
sc = device_get_softc(dev);
/* No SATA controller on the 88F5281 SoC */
if (d == MV_DEV_88F5281)
return (ENXIO);
switch(d) {
case MV_DEV_88F5182:
sc->sc_version = 1;

View File

@ -240,6 +240,9 @@
#define CPU_PM_CTRL_XOR (CPU_PM_CTRL_XOR0 | CPU_PM_CTRL_XOR1)
#define CPU_PM_CTRL_USB(u) (CPU_PM_CTRL_USB0)
#define CPU_PM_CTRL_SATA (CPU_PM_CTRL_SATA0 | CPU_PM_CTRL_SATA1)
#define CPU_PM_CTRL_GE(u) (CPU_PM_CTRL_GE1 * (u) | CPU_PM_CTRL_GE0 * \
(1 - (u)))
#define CPU_PM_CTRL_IDMA (CPU_PM_CTRL_NONE)
#elif defined(SOC_MV_DISCOVERY)
#define CPU_PM_CTRL_GE0 (1 << 1)
#define CPU_PM_CTRL_GE1 (1 << 2)
@ -264,12 +267,15 @@
#define CPU_PM_CTRL_DEVICE (1 << 23)
#define CPU_PM_CTRL_USB(u) (1 << (17 + (u)))
#define CPU_PM_CTRL_SATA (CPU_PM_CTRL_SATA0 | CPU_PM_CTRL_SATA1)
#define CPU_PM_CTRL_GE(u) (CPU_PM_CTRL_GE1 * (u) | CPU_PM_CTRL_GE0 * \
(1 - (u)))
#else
#define CPU_PM_CTRL_CRYPTO (CPU_PM_CTRL_NONE)
#define CPU_PM_CTRL_IDMA (CPU_PM_CTRL_NONE)
#define CPU_PM_CTRL_XOR (CPU_PM_CTRL_NONE)
#define CPU_PM_CTRL_SATA (CPU_PM_CTRL_NONE)
#define CPU_PM_CTRL_USB(u) (CPU_PM_CTRL_NONE)
#define CPU_PM_CTRL_GE(u) (CPU_PM_CTRL_NONE)
#endif
/*
@ -378,10 +384,14 @@
#define GPIO(n) (1 << (n))
#define MV_GPIO_MAX_NPINS 64
#define MV_GPIO_BLINK 0x1
#define MV_GPIO_POLAR_LOW 0x2
#define MV_GPIO_EDGE 0x4
#define MV_GPIO_LEVEL 0x8
#define MV_GPIO_IN_NONE 0x0
#define MV_GPIO_IN_POL_LOW (1 << 16)
#define MV_GPIO_IN_IRQ_EDGE (2 << 16)
#define MV_GPIO_IN_IRQ_LEVEL (4 << 16)
#define MV_GPIO_OUT_NONE 0x0
#define MV_GPIO_OUT_BLINK 0x1
#define MV_GPIO_OUT_OPEN_DRAIN 0x2
#define MV_GPIO_OUT_OPEN_SRC 0x4
#define IS_GPIO_IRQ(irq) ((irq) >= NIRQ && (irq) < NIRQ + MV_GPIO_MAX_NPINS)
#define GPIO2IRQ(gpio) ((gpio) + NIRQ)

View File

@ -48,51 +48,6 @@
#define MV_TYPE_PCI 0
#define MV_TYPE_PCIE 1
#define MV_TYPE_PCIE_AGGR_LANE 2 /* Additional PCIE lane to aggregate */
struct obio_softc {
bus_space_tag_t obio_bst; /* bus space tag */
struct rman obio_mem;
struct rman obio_irq;
struct rman obio_gpio;
};
struct obio_device {
const char *od_name;
u_long od_base;
u_long od_size;
u_int od_irqs[7 + 1]; /* keep additional entry for -1 sentinel */
u_int od_gpio[2 + 1]; /* as above for IRQ */
u_int od_pwr_mask;
struct resource_list od_resources;
};
struct obio_pci_irq_map {
int opim_slot;
int opim_pin;
int opim_irq;
};
struct obio_pci {
int op_type;
bus_addr_t op_base;
u_long op_size;
/* Note IO/MEM regions are assumed VA == PA */
bus_addr_t op_io_base;
u_long op_io_size;
int op_io_win_target;
int op_io_win_attr;
bus_addr_t op_mem_base;
u_long op_mem_size;
int op_mem_win_target;
int op_mem_win_attr;
const struct obio_pci_irq_map *op_pci_irq_map;
int op_irq; /* used if IRQ map table is NULL */
};
struct gpio_config {
int gc_gpio; /* GPIO number */
@ -109,14 +64,9 @@ struct decode_win {
};
extern const struct pmap_devmap pmap_devmap[];
extern const struct obio_pci mv_pci_info[];
extern const struct gpio_config mv_gpio_config[];
extern bus_space_tag_t obio_tag;
extern struct obio_device obio_devices[];
extern const struct decode_win *cpu_wins;
extern const struct decode_win *idma_wins;
extern const struct decode_win *xor_wins;
extern int cpu_wins_no;
extern int idma_wins_no;
extern int xor_wins_no;
@ -125,14 +75,12 @@ int mv_gpio_setup_intrhandler(const char *name, driver_filter_t *filt,
void (*hand)(void *), void *arg, int pin, int flags, void **cookiep);
void mv_gpio_intr_mask(int pin);
void mv_gpio_intr_unmask(int pin);
int mv_gpio_configure(uint32_t pin, uint32_t flags, uint32_t mask);
void mv_gpio_out(uint32_t pin, uint8_t val, uint8_t enable);
uint8_t mv_gpio_in(uint32_t pin);
int platform_gpio_init(void);
void platform_mpp_init(void);
int soc_decode_win(void);
void soc_id(uint32_t *dev, uint32_t *rev);
void soc_identify(void);
void soc_dump_decode_win(void);
uint32_t soc_power_ctrl_get(uint32_t mask);
void soc_power_ctrl_set(uint32_t mask);
@ -142,14 +90,6 @@ int decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size,
int decode_win_overlap(int, int, const struct decode_win *);
int win_cpu_can_remap(int);
void decode_win_idma_dump(void);
void decode_win_idma_setup(void);
int decode_win_idma_valid(void);
void decode_win_xor_dump(void);
void decode_win_xor_setup(void);
int decode_win_xor_valid(void);
int ddr_is_active(int i);
uint32_t ddr_base(int i);
uint32_t ddr_size(int i);
@ -161,15 +101,4 @@ uint32_t get_tclk(void);
uint32_t read_cpu_ctrl(uint32_t);
void write_cpu_ctrl(uint32_t, uint32_t);
enum mbus_device_ivars {
MBUS_IVAR_BASE,
};
#define MBUS_ACCESSOR(var, ivar, type) \
__BUS_ACCESSOR(mbus, var, MBUS, ivar, type)
MBUS_ACCESSOR(base, BASE, u_long)
#undef MBUS_ACCESSOR
#endif /* _MVVAR_H_ */

View File

@ -87,31 +87,14 @@
#define MV_BASE MV_PHYS_BASE /* VA == PA mapping */
#define MV_DDR_CADR_BASE (MV_BASE + 0x1500)
#define MV_MPP_BASE (MV_BASE + 0x10000)
#define MV_GPIO_BASE (MV_BASE + 0x10100)
#define MV_GPIO_SIZE 0x20
#define MV_RTC_BASE (MV_BASE + 0x10300)
#define MV_RTC_SIZE 0x08
#define MV_TWSI0_BASE (MV_BASE + 0x11000)
#define MV_TWSI1_BASE (MV_BASE + 0x11100)
#define MV_TWSI_SIZE 0x20
#define MV_UART0_BASE (MV_BASE + 0x12000)
#define MV_UART1_BASE (MV_BASE + 0x12100)
#define MV_UART_SIZE 0x20
#define MV_MBUS_BRIDGE_BASE (MV_BASE + 0x20000)
#define MV_INTREGS_BASE (MV_MBUS_BRIDGE_BASE + 0x80)
#define MV_CPU_CONTROL_BASE (MV_MBUS_BRIDGE_BASE + 0x100)
#define MV_IC_BASE (MV_MBUS_BRIDGE_BASE + 0x200)
#define MV_IC_SIZE 0x3C
#define MV_TIMERS_BASE (MV_MBUS_BRIDGE_BASE + 0x300)
#define MV_TIMERS_SIZE 0x30
#define MV_PCI_BASE (MV_BASE + 0x30000)
#define MV_PCI_SIZE 0x2000
#if defined (SOC_MV_KIRKWOOD)
#define MV_CESA_BASE (MV_BASE + 0x30000) /* CESA,PCI don't coexist */
#elif defined (SOC_MV_ORION) || defined(SOC_MV_DISCOVERY)
#define MV_CESA_BASE (MV_BASE + 0x90000)
#endif
#define MV_CESA_SIZE 0x10000
#define MV_PCIE_BASE (MV_BASE + 0x40000)
#define MV_PCIE_SIZE 0x2000
@ -124,27 +107,7 @@
#define MV_PCIE12_BASE (MV_PCIE_BASE + 0x48000)
#define MV_PCIE13_BASE (MV_PCIE_BASE + 0x4C000)
#define MV_USB0_BASE (MV_BASE + 0x50000)
#define MV_USB1_BASE (MV_USB0_BASE + 0x1000)
#define MV_USB2_BASE (MV_USB0_BASE + 0x2000)
#define MV_USB_SIZE 0x1000
#define MV_USB_AWR_BASE (MV_USB0_BASE + 0x320)
#define MV_IDMA_BASE (MV_BASE + 0x60000)
#define MV_IDMA_SIZE 0x1000
#define MV_XOR_BASE (MV_BASE + 0x60000)
#define MV_XOR_SIZE 0x1000
#define MV_ETH0_BASE (MV_BASE + 0x72000)
#define MV_ETH1_BASE (MV_BASE + 0x76000)
#define MV_ETH_SIZE 0x2000
#if defined(SOC_MV_ORION) || defined(SOC_MV_KIRKWOOD)
#define MV_SATAHC_BASE (MV_BASE + 0x80000)
#define MV_SATAHC_SIZE 0x6000
#elif defined(SOC_MV_DISCOVERY)
#define MV_SATAHC_BASE (MV_BASE + 0xA0000)
#define MV_SATAHC_SIZE 0x6000
#endif
#define MV_DEV_CS0_BASE MV_DEV_CS0_PHYS_BASE
#define MV_DEV_CS0_BASE MV_DEV_CS0_PHYS_BASE
/*
* Decode windows definitions and macros
@ -167,8 +130,16 @@
#define MV_WIN_CESA_BASE(n) (0x8 * (n) + 0xa00)
#define MV_WIN_CESA_MAX 4
#define MV_WIN_USB_CTRL(n, m) (0x10 * (n) + (m) * 0x1000 + 0x0)
#define MV_WIN_USB_BASE(n, m) (0x10 * (n) + (m) * 0x1000 + 0x4)
#if defined(SOC_MV_DISCOVERY)
#define MV_WIN_CESA_TARGET 9
#define MV_WIN_CESA_ATTR 1
#else
#define MV_WIN_CESA_TARGET 3
#define MV_WIN_CESA_ATTR 0
#endif
#define MV_WIN_USB_CTRL(n) (0x10 * (n) + 0x0)
#define MV_WIN_USB_BASE(n) (0x10 * (n) + 0x4)
#define MV_WIN_USB_MAX 4
#define MV_WIN_ETH_BASE(n) (0x8 * (n) + 0x200)
@ -192,6 +163,27 @@
#define MV_XOR_CHAN_MAX 2
#define MV_XOR_NON_REMAP 4
#if defined(SOC_MV_DISCOVERY)
#define MV_WIN_PCIE_MEM_TARGET 4
#define MV_WIN_PCIE_MEM_ATTR 0xE8
#define MV_WIN_PCIE_IO_TARGET 4
#define MV_WIN_PCIE_IO_ATTR 0xE0
#elif defined(SOC_MV_KIRKWOOD)
#define MV_WIN_PCIE_MEM_TARGET 4
#define MV_WIN_PCIE_MEM_ATTR 0xE8
#define MV_WIN_PCIE_IO_TARGET 4
#define MV_WIN_PCIE_IO_ATTR 0xE0
#elif defined(SOC_MV_ORION)
#define MV_WIN_PCIE_MEM_TARGET 4
#define MV_WIN_PCIE_MEM_ATTR 0x59
#define MV_WIN_PCIE_IO_TARGET 4
#define MV_WIN_PCIE_IO_ATTR 0x51
#define MV_WIN_PCI_MEM_TARGET 3
#define MV_WIN_PCI_MEM_ATTR 0x59
#define MV_WIN_PCI_IO_TARGET 3
#define MV_WIN_PCI_IO_ATTR 0x51
#endif
#define MV_WIN_PCIE_CTRL(n) (0x10 * (((n) < 5) ? (n) : \
(n) + 1) + 0x1820)
#define MV_WIN_PCIE_BASE(n) (0x10 * (((n) < 5) ? (n) : \
@ -211,70 +203,84 @@
static __inline uint32_t \
pre ## _ ## reg ## _read(int i) \
{ \
return (bus_space_read_4(obio_tag, base, off(i))); \
return (bus_space_read_4(fdtbus_bs_tag, base, off(i))); \
}
#define WIN_REG_IDX_RD2(pre,reg,off,base) \
static __inline uint32_t \
pre ## _ ## reg ## _read(int i, int j) \
{ \
return (bus_space_read_4(obio_tag, base, off(i, j))); \
return (bus_space_read_4(fdtbus_bs_tag, base, off(i, j))); \
} \
#define WIN_REG_BASE_IDX_RD(pre,reg,off) \
static __inline uint32_t \
pre ## _ ## reg ## _read(uint32_t base, int i) \
{ \
return (bus_space_read_4(obio_tag, base, off(i))); \
return (bus_space_read_4(fdtbus_bs_tag, base, off(i))); \
}
#define WIN_REG_BASE_IDX_RD2(pre,reg,off) \
static __inline uint32_t \
pre ## _ ## reg ## _read(uint32_t base, int i, int j) \
{ \
return (bus_space_read_4(fdtbus_bs_tag, base, off(i, j))); \
}
#define WIN_REG_IDX_WR(pre,reg,off,base) \
static __inline void \
pre ## _ ## reg ## _write(int i, uint32_t val) \
{ \
bus_space_write_4(obio_tag, base, off(i), val); \
bus_space_write_4(fdtbus_bs_tag, base, off(i), val); \
}
#define WIN_REG_IDX_WR2(pre,reg,off,base) \
static __inline void \
pre ## _ ## reg ## _write(int i, int j, uint32_t val) \
{ \
bus_space_write_4(obio_tag, base, off(i, j), val); \
bus_space_write_4(fdtbus_bs_tag, base, off(i, j), val); \
}
#define WIN_REG_BASE_IDX_WR(pre,reg,off) \
static __inline void \
pre ## _ ## reg ## _write(uint32_t base, int i, uint32_t val) \
{ \
bus_space_write_4(obio_tag, base, off(i), val); \
bus_space_write_4(fdtbus_bs_tag, base, off(i), val); \
}
#define WIN_REG_BASE_IDX_WR2(pre,reg,off) \
static __inline void \
pre ## _ ## reg ## _write(uint32_t base, int i, int j, uint32_t val) \
{ \
bus_space_write_4(fdtbus_bs_tag, base, off(i, j), val); \
}
#define WIN_REG_RD(pre,reg,off,base) \
static __inline uint32_t \
pre ## _ ## reg ## _read(void) \
{ \
return (bus_space_read_4(obio_tag, base, off)); \
return (bus_space_read_4(fdtbus_bs_tag, base, off)); \
}
#define WIN_REG_BASE_RD(pre,reg,off) \
static __inline uint32_t \
pre ## _ ## reg ## _read(uint32_t base) \
{ \
return (bus_space_read_4(obio_tag, base, off)); \
return (bus_space_read_4(fdtbus_bs_tag, base, off)); \
}
#define WIN_REG_WR(pre,reg,off,base) \
static __inline void \
pre ## _ ## reg ## _write(uint32_t val) \
{ \
bus_space_write_4(obio_tag, base, off, val); \
bus_space_write_4(fdtbus_bs_tag, base, off, val); \
}
#define WIN_REG_BASE_WR(pre,reg,off) \
static __inline void \
pre ## _ ## reg ## _write(uint32_t base, uint32_t val) \
{ \
bus_space_write_4(obio_tag, base, off, val); \
bus_space_write_4(fdtbus_bs_tag, base, off, val); \
}
#endif /* _MVWIN_H_ */

View File

@ -1,374 +0,0 @@
/*-
* Copyright (c) 2006 Benno Rice. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* from: FreeBSD: //depot/projects/arm/src/sys/arm/xscale/pxa2x0/pxa2x0_obio.c, rev 1
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/rman.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <arm/mv/mvvar.h>
#include <arm/mv/mvreg.h>
static void mbus_identify(driver_t *, device_t);
static int mbus_probe(device_t);
static int mbus_attach(device_t);
static void
mbus_identify(driver_t *driver, device_t parent)
{
BUS_ADD_CHILD(parent, 0, "mbus", 0);
}
static int
mbus_probe(device_t dev)
{
device_set_desc(dev, "Marvell Internal Bus (Mbus)");
return (0);
}
static int
mbus_attach(device_t dev)
{
struct obio_softc *sc;
struct obio_device *od;
int i;
device_t child;
sc = device_get_softc(dev);
sc->obio_bst = obio_tag;
sc->obio_mem.rm_type = RMAN_ARRAY;
sc->obio_mem.rm_descr = "Marvell OBIO Memory";
if (rman_init(&sc->obio_mem) != 0)
panic("mbus_attach: failed to init obio mem rman");
if (rman_manage_region(&sc->obio_mem, 0, ~0) != 0)
panic("mbus_attach: failed to set up obio mem rman");
sc->obio_irq.rm_type = RMAN_ARRAY;
sc->obio_irq.rm_descr = "Marvell OBIO IRQ";
if (rman_init(&sc->obio_irq) != 0)
panic("mbus_attach: failed to init obio irq rman");
if (rman_manage_region(&sc->obio_irq, 0, NIRQ - 1) != 0)
panic("mbus_attach: failed to set up obio irq rman");
sc->obio_gpio.rm_type = RMAN_ARRAY;
sc->obio_gpio.rm_descr = "Marvell GPIO";
if (rman_init(&sc->obio_gpio) != 0)
panic("mbus_attach: failed to init gpio rman");
if (rman_manage_region(&sc->obio_gpio, 0, MV_GPIO_MAX_NPINS - 1) != 0)
panic("mbus_attach: failed to set up gpio rman");
for (od = obio_devices; od->od_name != NULL; od++) {
if (soc_power_ctrl_get(od->od_pwr_mask) != od->od_pwr_mask)
continue;
resource_list_init(&od->od_resources);
resource_list_add(&od->od_resources, SYS_RES_MEMORY, 0,
od->od_base, od->od_base + od->od_size - 1, od->od_size);
for (i = 0; od->od_irqs[i] != -1; i++) {
resource_list_add(&od->od_resources, SYS_RES_IRQ, i,
od->od_irqs[i], od->od_irqs[i], 1);
}
for (i = 0; od->od_gpio[i] != -1; i++) {
resource_list_add(&od->od_resources, SYS_RES_GPIO, i,
od->od_gpio[i], od->od_gpio[i], 1);
}
child = device_add_child(dev, od->od_name, -1);
device_set_ivars(child, od);
}
bus_generic_probe(dev);
bus_generic_attach(dev);
return (0);
}
static int
mbus_print_child(device_t dev, device_t child)
{
struct obio_device *od;
int rv;
od = (struct obio_device *)device_get_ivars(child);
if (od == NULL)
panic("Unknown device on %s", device_get_nameunit(dev));
rv = bus_print_child_header(dev, child);
rv += resource_list_print_type(&od->od_resources, "at mem",
SYS_RES_MEMORY, "0x%08lx");
rv += resource_list_print_type(&od->od_resources, "irq",
SYS_RES_IRQ, "%ld");
rv += resource_list_print_type(&od->od_resources, "gpio",
SYS_RES_GPIO, "%ld");
if (device_get_flags(child))
rv += printf(" flags %#x", device_get_flags(child));
rv += bus_print_child_footer(dev, child);
return (rv);
}
static int
mbus_setup_intr(device_t dev, device_t child, struct resource *ires, int flags,
driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep)
{
struct obio_softc *sc;
int error;
sc = (struct obio_softc *)device_get_softc(dev);
if (rman_is_region_manager(ires, &sc->obio_gpio)) {
error = mv_gpio_setup_intrhandler(
device_get_nameunit(child), filt, intr, arg,
rman_get_start(ires), flags, cookiep);
if (error != 0)
return (error);
mv_gpio_intr_unmask(rman_get_start(ires));
return (0);
}
BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, filt, intr, arg,
cookiep);
arm_unmask_irq(rman_get_start(ires));
return (0);
}
static int
mbus_teardown_intr(device_t dev, device_t child, struct resource *ires, void *cookie)
{
return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, ires, cookie));
}
static int
mbus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct obio_device *od;
od = (struct obio_device *)device_get_ivars(child);
switch (which) {
case MBUS_IVAR_BASE:
*((u_long *)result) = od->od_base;
break;
default:
return (ENOENT);
}
return (0);
}
static struct resource_list *
mbus_get_resource_list(device_t dev, device_t child)
{
struct obio_device *od;
od = (struct obio_device *)device_get_ivars(child);
if (od == NULL)
return (NULL);
return (&od->od_resources);
}
static struct resource *
mbus_alloc_resource(device_t dev, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct obio_softc *sc;
struct obio_device *od;
struct resource *rv;
struct resource_list *rl;
struct resource_list_entry *rle = NULL;
struct rman *rm;
int needactivate;
sc = (struct obio_softc *)device_get_softc(dev);
if (type == SYS_RES_IRQ && IS_GPIO_IRQ(start)) {
type = SYS_RES_GPIO;
start = IRQ2GPIO(start);
}
switch (type) {
case SYS_RES_IRQ:
rm = &sc->obio_irq;
break;
case SYS_RES_MEMORY:
rm = &sc->obio_mem;
break;
case SYS_RES_GPIO:
rm = &sc->obio_gpio;
break;
default:
return (NULL);
}
if (device_get_parent(child) == dev) {
od = (struct obio_device *)device_get_ivars(child);
rl = &od->od_resources;
rle = resource_list_find(rl, type, *rid);
if (rle->res != NULL)
panic("mbus_alloc_resource: resource is busy");
}
if (rle) {
start = rle->start;
end = rle->end;
count = rle->count;
}
needactivate = flags & RF_ACTIVE;
flags &= ~RF_ACTIVE;
rv = rman_reserve_resource(rm, start, end, count, flags, child);
if (rv == NULL)
return (NULL);
if (rle)
rle->res = rv;
rman_set_rid(rv, *rid);
if (type == SYS_RES_MEMORY) {
rman_set_bustag(rv, sc->obio_bst);
rman_set_bushandle(rv, start);
}
if (needactivate)
if (bus_activate_resource(child, type, *rid, rv)) {
rman_release_resource(rv);
return (NULL);
}
return (rv);
}
static int
mbus_release_resource(device_t dev, device_t child, int type, int rid,
struct resource *r)
{
struct obio_device *od;
struct resource_list *rl;
struct resource_list_entry *rle;
if (device_get_parent(child) == dev) {
od = (struct obio_device *)device_get_ivars(child);
rl = &od->od_resources;
rle = resource_list_find(rl, type, rid);
if (!rle)
panic("mbus_release_resource: can't find resource");
if (!rle->res)
panic("mbus_release_resource: resource entry is not busy");
r = rle->res;
rle->res = NULL;
}
rman_release_resource(r);
return (0);
}
static int
mbus_activate_resource(device_t dev, device_t child, int type, int rid,
struct resource *r)
{
return (rman_activate_resource(r));
}
static device_t
mbus_add_child(device_t bus, int order, const char *name, int unit)
{
struct obio_device *od;
device_t child;
od = malloc(sizeof(struct obio_device), M_DEVBUF, M_NOWAIT | M_ZERO);
if (!od)
return (0);
resource_list_init(&od->od_resources);
od->od_name = name;
child = device_add_child_ordered(bus, order, name, unit);
device_set_ivars(child, od);
return (child);
}
static device_method_t mbus_methods[] = {
DEVMETHOD(device_identify, mbus_identify),
DEVMETHOD(device_probe, mbus_probe),
DEVMETHOD(device_attach, mbus_attach),
DEVMETHOD(bus_add_child, mbus_add_child),
DEVMETHOD(bus_print_child, mbus_print_child),
DEVMETHOD(bus_read_ivar, mbus_read_ivar),
DEVMETHOD(bus_setup_intr, mbus_setup_intr),
DEVMETHOD(bus_teardown_intr, mbus_teardown_intr),
DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
DEVMETHOD(bus_get_resource_list, mbus_get_resource_list),
DEVMETHOD(bus_alloc_resource, mbus_alloc_resource),
DEVMETHOD(bus_release_resource, mbus_release_resource),
DEVMETHOD(bus_activate_resource, mbus_activate_resource),
{0, 0}
};
static driver_t mbus_driver = {
"mbus",
mbus_methods,
sizeof(struct obio_softc),
};
static devclass_t mbus_devclass;
DRIVER_MODULE(mbus, nexus, mbus_driver, mbus_devclass, 0, 0);

View File

@ -70,6 +70,8 @@ __FBSDID("$FreeBSD$");
* 0xffff_2000 - 0xffff_ffff : unused (~55KB)
*/
#if 0
int platform_pci_get_irq(u_int bus, u_int slot, u_int func, u_int pin);
/* Static device mappings. */
@ -140,7 +142,6 @@ const struct obio_pci_irq_map pci_irq_map[] = {
{ -1, -1, -1 }
};
#if 0
/* PCI IRQ Map for DB-88F5182 */
const struct obio_pci_irq_map pci_irq_map[] = {
{ 7, -1, GPIO2IRQ(0) },
@ -150,6 +151,7 @@ const struct obio_pci_irq_map pci_irq_map[] = {
};
#endif
#if 0
/*
* mv_gpio_config row structure:
* <GPIO number>, <GPIO flags>, <GPIO mode>
@ -182,72 +184,4 @@ const struct gpio_config mv_gpio_config[] = {
};
#endif
void
platform_mpp_init(void)
{
/*
* MPP configuration for DB-88F5281
*
* MPP[2]: PCI_REQn[3]
* MPP[3]: PCI_GNTn[3]
* MPP[4]: PCI_REQn[4]
* MPP[5]: PCI_GNTn[4]
* MPP[6]: <UNKNOWN>
* MPP[7]: <UNKNOWN>
* MPP[8]: <UNKNOWN>
* MPP[9]: <UNKNOWN>
* MPP[14]: NAND Flash REn[2]
* MPP[15]: NAND Flash WEn[2]
* MPP[16]: UA1_RXD
* MPP[17]: UA1_TXD
* MPP[18]: UA1_CTS
* MPP[19]: UA1_RTS
*
* Others: GPIO
*
* <UNKNOWN> entries are not documented, not on the schematics etc.
*/
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL0, 0x33222203);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL1, 0x44000033);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL2, 0x00000000);
#if 0
/*
* MPP configuration for DB-88F5182
*
* MPP[2]: PCI_REQn[3]
* MPP[3]: PCI_GNTn[3]
* MPP[4]: PCI_REQn[4]
* MPP[5]: PCI_GNTn[4]
* MPP[6]: SATA0_ACT
* MPP[7]: SATA1_ACT
* MPP[12]: SATA0_PRESENT
* MPP[13]: SATA1_PRESENT
* MPP[14]: NAND_FLASH_REn[2]
* MPP[15]: NAND_FLASH_WEn[2]
* MPP[16]: UA1_RXD
* MPP[17]: UA1_TXD
* MPP[18]: UA1_CTS
* MPP[19]: UA1_RTS
*
* Others: GPIO
*/
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL0, 0x55222203);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL1, 0x44550000);
bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL2, 0x00000000);
#endif
}
static void
platform_identify(void *dummy)
{
soc_identify();
/*
* XXX Board identification e.g. read out from FPGA or similar should
* go here
*/
}
SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify, NULL);

View File

@ -37,68 +37,14 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <machine/bus.h>
#include <machine/fdt.h>
#include <arm/mv/mvreg.h>
#include <arm/mv/mvvar.h>
#include <arm/mv/mvwin.h>
#if 0
extern const struct obio_pci_irq_map pci_irq_map[];
struct obio_device obio_devices[] = {
{ "ic", MV_IC_BASE, MV_IC_SIZE,
{ -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "timer", MV_TIMERS_BASE, MV_TIMERS_SIZE,
{ MV_INT_BRIDGE, -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "gpio", MV_GPIO_BASE, MV_GPIO_SIZE,
{ MV_INT_GPIO7_0, MV_INT_GPIO15_8,
MV_INT_GPIO23_16, MV_INT_GPIO31_24, -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "uart", MV_UART0_BASE, MV_UART_SIZE,
{ MV_INT_UART0, -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "uart", MV_UART1_BASE, MV_UART_SIZE,
{ MV_INT_UART1, -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "idma", MV_IDMA_BASE, MV_IDMA_SIZE,
{ MV_INT_IDMA_ERR, MV_INT_IDMA0, MV_INT_IDMA1,
MV_INT_IDMA2, MV_INT_IDMA3, -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "ehci", MV_USB0_BASE, MV_USB_SIZE,
{ MV_INT_USB_BERR, MV_INT_USB_CI, -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "mge", MV_ETH0_BASE, MV_ETH_SIZE,
{ MV_INT_GBERX, MV_INT_GBETX, MV_INT_GBEMISC,
MV_INT_GBESUM, MV_INT_GBEERR, -1 },
{ -1 },
CPU_PM_CTRL_NONE
},
{ "twsi", MV_TWSI0_BASE, MV_TWSI_SIZE,
{ -1 }, { -1 },
CPU_PM_CTRL_NONE
},
{ "sata", MV_SATAHC_BASE, MV_SATAHC_SIZE,
{ MV_INT_SATA, -1 }, { -1 },
CPU_PM_CTRL_NONE
},
{ NULL, 0, 0, { 0 } }
};
const struct obio_pci mv_pci_info[] = {
{ MV_TYPE_PCIE,
MV_PCIE_BASE, MV_PCIE_SIZE,
@ -116,6 +62,7 @@ const struct obio_pci mv_pci_info[] = {
{ 0, 0, 0 }
};
#endif
struct resource_spec mv_gpio_res[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
@ -126,52 +73,11 @@ struct resource_spec mv_gpio_res[] = {
{ -1, 0 }
};
const struct decode_win cpu_win_tbl[] = {
/* Device bus BOOT */
{ 1, 0x0f, MV_DEV_BOOT_PHYS_BASE, MV_DEV_BOOT_SIZE, -1 },
/* Device bus CS0 */
{ 1, 0x1e, MV_DEV_CS0_PHYS_BASE, MV_DEV_CS0_SIZE, -1 },
/* Device bus CS1 */
{ 1, 0x1d, MV_DEV_CS1_PHYS_BASE, MV_DEV_CS1_SIZE, -1 },
/* Device bus CS2 */
{ 1, 0x1b, MV_DEV_CS2_PHYS_BASE, MV_DEV_CS2_SIZE, -1 },
};
const struct decode_win *cpu_wins = cpu_win_tbl;
int cpu_wins_no = sizeof(cpu_win_tbl) / sizeof(struct decode_win);
/*
* Note: the decode windows table for IDMA does not explicitly have DRAM
* entries, which are not statically defined: active DDR banks (== windows)
* are established in run time from actual DDR windows settings. All active
* DDR banks are mapped into IDMA decode windows, so at least one IDMA decode
* window is occupied by the DDR bank; in case when all (MV_WIN_DDR_MAX)
* DDR banks are active, the remaining available IDMA decode windows for other
* targets is only MV_WIN_IDMA_MAX - MV_WIN_DDR_MAX.
*/
const struct decode_win idma_win_tbl[] = {
/* PCIE MEM */
{ 4, 0x59, MV_PCIE_MEM_PHYS_BASE, MV_PCIE_MEM_SIZE, -1 },
/* PCI MEM */
{ 3, 0x59, MV_PCI_MEM_PHYS_BASE, MV_PCI_MEM_SIZE, -1 },
/* Device bus BOOT */
{ 1, 0x0f, MV_DEV_BOOT_PHYS_BASE, MV_DEV_BOOT_SIZE, -1 },
/* Device bus CS0 */
{ 1, 0x1e, MV_DEV_CS0_PHYS_BASE, MV_DEV_CS0_SIZE, -1 },
/* Device bus CS1 */
{ 1, 0x1d, MV_DEV_CS1_PHYS_BASE, MV_DEV_CS1_SIZE, -1 },
/* Device bus CS2 */
{ 1, 0x1b, MV_DEV_CS2_PHYS_BASE, MV_DEV_CS2_SIZE, -1 },
{ 0 },
};
const struct decode_win *idma_wins = idma_win_tbl;
int idma_wins_no = sizeof(idma_win_tbl) / sizeof(struct decode_win);
int idma_wins_no = 0;
uint32_t
get_tclk(void)
@ -182,7 +88,8 @@ get_tclk(void)
* On Orion TCLK is can be configured to 150 MHz or 166 MHz.
* Current setting is read from Sample At Reset register.
*/
sar = bus_space_read_4(obio_tag, MV_MPP_BASE, SAMPLE_AT_RESET);
/* XXX MPP addr should be retrieved from the DT */
sar = bus_space_read_4(fdtbus_bs_tag, MV_MPP_BASE, SAMPLE_AT_RESET);
sar = (sar & TCLK_MASK) >> TCLK_SHIFT;
switch (sar) {
case 1:

View File

@ -45,6 +45,9 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/resource.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include "clock_if.h"
#define MV_RTC_TIME_REG 0x00
@ -88,14 +91,17 @@ static driver_t mv_rtc_driver = {
};
static devclass_t mv_rtc_devclass;
DRIVER_MODULE(mv_rtc, mbus, mv_rtc_driver, mv_rtc_devclass, 0, 0);
DRIVER_MODULE(mv_rtc, simplebus, mv_rtc_driver, mv_rtc_devclass, 0, 0);
static int
mv_rtc_probe(device_t dev)
{
if (!ofw_bus_is_compatible(dev, "mrvl,rtc"))
return (ENXIO);
device_set_desc(dev, "Marvell Integrated RTC");
return (0);
return (BUS_PROBE_DEFAULT);
}
static int

View File

@ -48,6 +48,9 @@ __FBSDID("$FreeBSD$");
#include <arm/mv/mvreg.h>
#include <arm/mv/mvvar.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#define MV_TIMER_TICK (get_tclk() / hz)
#define INITIAL_TIMECOUNTER (0xffffffff)
#define MAX_WATCHDOG_TICKS (0xffffffff)
@ -97,6 +100,9 @@ static int
mv_timer_probe(device_t dev)
{
if (!ofw_bus_is_compatible(dev, "mrvl,timer"))
return (ENXIO);
device_set_desc(dev, "Marvell CPU Timer");
return (0);
}
@ -171,7 +177,7 @@ static driver_t mv_timer_driver = {
static devclass_t mv_timer_devclass;
DRIVER_MODULE(timer, mbus, mv_timer_driver, mv_timer_devclass, 0, 0);
DRIVER_MODULE(timer, simplebus, mv_timer_driver, mv_timer_devclass, 0, 0);
static unsigned
mv_timer_get_timecount(struct timecounter *tc)

View File

@ -57,6 +57,9 @@ __FBSDID("$FreeBSD$");
#include <dev/iicbus/iiconf.h>
#include <dev/iicbus/iicbus.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include "iicbus_if.h"
#define MV_TWSI_NAME "twsi"
@ -151,7 +154,7 @@ static driver_t mv_twsi_driver = {
sizeof(struct mv_twsi_softc),
};
DRIVER_MODULE(twsi, mbus, mv_twsi_driver, mv_twsi_devclass, 0, 0);
DRIVER_MODULE(twsi, simplebus, mv_twsi_driver, mv_twsi_devclass, 0, 0);
DRIVER_MODULE(iicbus, twsi, iicbus_driver, iicbus_devclass, 0, 0);
MODULE_DEPEND(twsi, iicbus, 1, 1, 1);
@ -289,6 +292,9 @@ static int
mv_twsi_probe(device_t dev)
{
if (!ofw_bus_is_compatible(dev, "mrvl,twsi"))
return (ENXIO);
device_set_desc(dev, "Marvell Integrated I2C Bus Controller");
return (BUS_PROBE_DEFAULT);
}

View File

@ -30,6 +30,8 @@ S= ../../..
.endif
.include "$S/conf/kern.pre.mk"
INCLUDES+= -I$S/contrib/libfdt
SYSTEM_LD:= ${SYSTEM_LD:$S/conf/ldscript.$M=ldscript.$M}
SYSTEM_DEP:= ${SYSTEM_DEP:$S/conf/ldscript.$M=ldscript.$M}

View File

@ -47,7 +47,14 @@ arm/arm/vm_machdep.c standard
arm/fpe-arm/armfpe_glue.S optional armfpe
arm/fpe-arm/armfpe_init.c optional armfpe
arm/fpe-arm/armfpe.S optional armfpe
dev/fdt/fdt_arm.c optional fdt
dev/hwpmc/hwpmc_arm.c optional hwpmc
dev/ofw/openfirm.c optional fdt
dev/ofw/openfirmio.c optional fdt
dev/ofw/ofw_bus_if.m optional fdt
dev/ofw/ofw_if.m optional fdt
dev/ofw/ofw_bus_subr.c optional fdt
dev/ofw/ofw_fdt.c optional fdt
geom/geom_bsd.c optional geom_bsd
geom/geom_bsd_enc.c optional geom_bsd
geom/geom_mbr.c optional geom_mbr
@ -62,6 +69,7 @@ libkern/ffsl.c standard
libkern/fls.c standard
libkern/flsl.c standard
libkern/lshrdi3.c standard
libkern/memchr.c optional fdt
libkern/moddi3.c standard
libkern/qdivrem.c standard
libkern/udivdi3.c standard

View File

@ -24,7 +24,6 @@ KERNVIRTADDR opt_global.h
LOADERRAMADDR opt_global.h
PHYSADDR opt_global.h
PHYSMEM_SIZE opt_global.h
MII_ADDR_BASE opt_global.h
SKYEYE_WORKAROUNDS opt_global.h
SOC_MV_DISCOVERY opt_global.h
SOC_MV_KIRKWOOD opt_global.h

View File

@ -69,9 +69,9 @@ __FBSDID("$FreeBSD$");
#include <dev/mii/mii.h>
#include <dev/mii/miivar.h>
#ifndef MII_ADDR_BASE
#define MII_ADDR_BASE 8
#endif
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/mge/if_mgevar.h>
#include <arm/mv/mvreg.h>
@ -164,7 +164,7 @@ static driver_t mge_driver = {
static devclass_t mge_devclass;
DRIVER_MODULE(mge, mbus, mge_driver, mge_devclass, 0, 0);
DRIVER_MODULE(mge, simplebus, mge_driver, mge_devclass, 0, 0);
DRIVER_MODULE(miibus, mge, miibus_driver, miibus_devclass, 0, 0);
MODULE_DEPEND(mge, ether, 1, 1, 1);
MODULE_DEPEND(mge, miibus, 1, 1, 1);
@ -194,10 +194,30 @@ static void
mge_get_mac_address(struct mge_softc *sc, uint8_t *addr)
{
uint32_t mac_l, mac_h;
uint8_t lmac[6];
int i, valid;
/* XXX use currently programmed MAC address; eventually this info will
* be provided by the loader */
/*
* Retrieve hw address from the device tree.
*/
i = OF_getprop(sc->node, "local-mac-address", (void *)lmac, 6);
if (i == 6) {
valid = 0;
for (i = 0; i < 6; i++)
if (lmac[i] != 0) {
valid = 1;
break;
}
if (valid) {
bcopy(lmac, addr, 6);
return;
}
}
/*
* Fall back -- use the currently programmed address.
*/
mac_l = MGE_READ(sc, MGE_MAC_ADDR_L);
mac_h = MGE_READ(sc, MGE_MAC_ADDR_H);
@ -613,6 +633,7 @@ mge_attach(device_t dev)
sc = device_get_softc(dev);
sc->dev = dev;
sc->node = ofw_bus_get_node(dev);
if (device_get_unit(dev) == 0)
sc_mge0 = sc;
@ -620,6 +641,10 @@ mge_attach(device_t dev)
/* Set chip version-dependent parameters */
mge_ver_params(sc);
/* Get phy address from fdt */
if (fdt_get_phyaddr(sc->node, &sc->phyaddr) != 0)
return (ENXIO);
/* Initialize mutexes */
mtx_init(&sc->transmit_lock, device_get_nameunit(dev), "mge TX lock", MTX_DEF);
mtx_init(&sc->receive_lock, device_get_nameunit(dev), "mge RX lock", MTX_DEF);
@ -1263,19 +1288,12 @@ mge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
static int
mge_miibus_readreg(device_t dev, int phy, int reg)
{
struct mge_softc *sc;
uint32_t retries;
/*
* We assume static PHY address <=> device unit mapping:
* PHY Address = MII_ADDR_BASE + devce unit.
* This is true for most Marvell boards.
*
* Code below grants proper PHY detection on each device
* unit.
*/
sc = device_get_softc(dev);
if ((MII_ADDR_BASE + device_get_unit(dev)) != phy)
if (sc->phyaddr != phy)
return (0);
MGE_WRITE(sc_mge0, MGE_REG_SMI, 0x1fffffff &
@ -1294,9 +1312,12 @@ mge_miibus_readreg(device_t dev, int phy, int reg)
static int
mge_miibus_writereg(device_t dev, int phy, int reg, int value)
{
struct mge_softc *sc;
uint32_t retries;
if ((MII_ADDR_BASE + device_get_unit(dev)) != phy)
sc = device_get_softc(dev);
if (sc->phyaddr != phy)
return (0);
MGE_WRITE(sc_mge0, MGE_REG_SMI, 0x1fffffff &
@ -1315,6 +1336,9 @@ static int
mge_probe(device_t dev)
{
if (!ofw_bus_is_compatible(dev, "mrvl,ge"))
return (ENXIO);
device_set_desc(dev, "Marvell Gigabit Ethernet controller");
return (BUS_PROBE_DEFAULT);
}

View File

@ -64,8 +64,12 @@ struct mge_desc_wrapper {
struct mge_softc {
struct ifnet *ifp; /* per-interface network data */
phandle_t node;
device_t dev;
device_t miibus;
struct mii_data *mii;
struct resource *res[1 + MGE_INTR_COUNT]; /* resources */
void *ih_cookie[MGE_INTR_COUNT]; /* interrupt handlers cookies */
@ -99,6 +103,8 @@ struct mge_softc {
uint32_t mge_tx_tok_cnt;
uint16_t mge_mtu;
int mge_ver;
int phyaddr;
};

View File

@ -1,81 +0,0 @@
/*-
* Copyright (C) 2007 MARVELL INTERNATIONAL LTD.
* All rights reserved.
*
* Developed by Semihalf.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of MARVELL nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <dev/uart/uart.h>
#include <dev/uart/uart_bus.h>
#include <dev/uart/uart_cpu.h>
#include <arm/mv/mvvar.h>
static int uart_mbus_probe(device_t dev);
static device_method_t uart_mbus_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, uart_mbus_probe),
DEVMETHOD(device_attach, uart_bus_attach),
DEVMETHOD(device_detach, uart_bus_detach),
{ 0, 0 }
};
static driver_t uart_mbus_driver = {
uart_driver_name,
uart_mbus_methods,
sizeof(struct uart_softc),
};
static int
uart_mbus_probe(device_t dev)
{
struct uart_softc *sc;
int status;
sc = device_get_softc(dev);
sc->sc_class = &uart_ns8250_class;
status = uart_bus_probe(dev, 2, get_tclk(), 0, 0);
return(status);
}
DRIVER_MODULE(uart, mbus, uart_mbus_driver, uart_devclass, 0, 0);

View File

@ -1,92 +0,0 @@
/*-
* Copyright (C) 2007 MARVELL INTERNATIONAL LTD.
* All rights reserved.
*
* Developed by Semihalf.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of MARVELL nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "opt_uart.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/cons.h>
#include <machine/bus.h>
#include <dev/uart/uart.h>
#include <dev/uart/uart_cpu.h>
#include <arm/mv/mvreg.h>
#include <arm/mv/mvvar.h>
#include <arm/mv/mvwin.h>
bus_space_tag_t uart_bus_space_io;
bus_space_tag_t uart_bus_space_mem;
int
uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
{
return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0);
}
int
uart_cpu_getdev(int devtype, struct uart_devinfo *di)
{
struct uart_class *class = &uart_ns8250_class;
/*
* If env specification for UART exists it takes precedence:
* hw.uart.console="mm:0xf1012000" or similar
*/
if (uart_getenv(devtype, di, class) == 0)
return (0);
/*
* Fall back to default UART0 console settings
*/
di->ops = uart_getops(class);
di->bas.chan = 0;
di->bas.bst = obio_tag;
if (bus_space_map(di->bas.bst, MV_UART0_BASE, MV_UART_SIZE,
0, &di->bas.bsh) != 0)
return (ENXIO);
di->baudrate = 0;
di->bas.regshft = 2;
di->bas.rclk = get_tclk();
di->databits = 8;
di->stopbits = 1;
di->parity = UART_PARITY_NONE;
uart_bus_space_mem = obio_tag;
uart_bus_space_io = NULL;
return (0);
}

View File

@ -30,7 +30,7 @@
*/
/*
* MBus attachment driver for the USB Enhanced Host Controller.
* FDT attachment driver for the USB Enhanced Host Controller.
*/
#include <sys/cdefs.h>
@ -58,6 +58,9 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/priv.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@ -77,11 +80,11 @@ __FBSDID("$FreeBSD$");
#define EHCI_VENDORID_MRVL 0x1286
#define EHCI_HC_DEVSTR "Marvell Integrated USB 2.0 controller"
static device_attach_t ehci_mbus_attach;
static device_detach_t ehci_mbus_detach;
static device_shutdown_t ehci_mbus_shutdown;
static device_suspend_t ehci_mbus_suspend;
static device_resume_t ehci_mbus_resume;
static device_attach_t mv_ehci_attach;
static device_detach_t mv_ehci_detach;
static device_shutdown_t mv_ehci_shutdown;
static device_suspend_t mv_ehci_suspend;
static device_resume_t mv_ehci_resume;
static int err_intr(void *arg);
@ -100,7 +103,7 @@ static void *ih_err;
#define MV_USB_DEVICE_UNDERFLOW (1 << 3)
static int
ehci_mbus_suspend(device_t self)
mv_ehci_suspend(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
int err;
@ -113,7 +116,7 @@ ehci_mbus_suspend(device_t self)
}
static int
ehci_mbus_resume(device_t self)
mv_ehci_resume(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
@ -125,7 +128,7 @@ ehci_mbus_resume(device_t self)
}
static int
ehci_mbus_shutdown(device_t self)
mv_ehci_shutdown(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
int err;
@ -139,16 +142,19 @@ ehci_mbus_shutdown(device_t self)
}
static int
ehci_mbus_probe(device_t self)
mv_ehci_probe(device_t self)
{
if (!ofw_bus_is_compatible(self, "mrvl,usb-ehci"))
return (ENXIO);
device_set_desc(self, EHCI_HC_DEVSTR);
return (BUS_PROBE_DEFAULT);
}
static int
ehci_mbus_attach(device_t self)
mv_ehci_attach(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
bus_space_handle_t bsh;
@ -177,10 +183,11 @@ ehci_mbus_attach(device_t self)
sc->sc_io_size = rman_get_size(sc->sc_io_res) - MV_USB_HOST_OFST;
/*
* Marvell EHCI host controller registers start at certain offset within
* the whole USB registers range, so create a subregion for the host
* mode configuration purposes.
* Marvell EHCI host controller registers start at certain offset
* within the whole USB registers range, so create a subregion for the
* host mode configuration purposes.
*/
if (bus_space_subregion(sc->sc_io_tag, bsh, MV_USB_HOST_OFST,
sc->sc_io_size, &sc->sc_io_hdl) != 0)
panic("%s: unable to subregion USB host registers",
@ -191,14 +198,14 @@ ehci_mbus_attach(device_t self)
RF_SHAREABLE | RF_ACTIVE);
if (irq_err == NULL) {
device_printf(self, "Could not allocate error irq\n");
ehci_mbus_detach(self);
mv_ehci_detach(self);
return (ENXIO);
}
/*
* Notice: Marvell EHCI controller has TWO interrupt lines, so make sure to
* use the correct rid for the main one (controller interrupt) --
* refer to obio_devices[] for the right resource number to use here.
* Notice: Marvell EHCI controller has TWO interrupt lines, so make
* sure to use the correct rid for the main one (controller interrupt)
* -- refer to DTS for the right resource number to use here.
*/
rid = 1;
sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
@ -216,7 +223,7 @@ ehci_mbus_attach(device_t self)
device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
device_set_desc(sc->sc_bus.bdev, EHCI_HC_DEVSTR);
sprintf(sc->sc_vendor, "Marvell");
sprintf(sc->sc_vendor, "Marvell");
err = bus_setup_intr(self, irq_err, INTR_FAST | INTR_TYPE_BIO,
err_intr, NULL, sc, &ih_err);
@ -238,7 +245,7 @@ ehci_mbus_attach(device_t self)
goto error;
}
/*
/*
* Workaround for Marvell integrated EHCI controller: reset of
* the EHCI core clears the USBMODE register, which sets the core in
* an undefined state (neither host nor agent), so it needs to be set
@ -265,18 +272,18 @@ ehci_mbus_attach(device_t self)
return (0);
error:
ehci_mbus_detach(self);
mv_ehci_detach(self);
return (ENXIO);
}
static int
ehci_mbus_detach(device_t self)
mv_ehci_detach(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
device_t bdev;
int err;
if (sc->sc_bus.bdev) {
if (sc->sc_bus.bdev) {
bdev = sc->sc_bus.bdev;
device_detach(bdev);
device_delete_child(self, bdev);
@ -291,7 +298,7 @@ ehci_mbus_detach(device_t self)
EWRITE4(sc, EHCI_USBINTR, 0);
EWRITE4(sc, USB_BRIDGE_INTR_MASK, 0);
}
if (sc->sc_irq_res && sc->sc_intr_hdl) {
if (sc->sc_irq_res && sc->sc_intr_hdl) {
/*
* only call ehci_detach() after ehci_init()
*/
@ -305,7 +312,7 @@ ehci_mbus_detach(device_t self)
err);
sc->sc_intr_hdl = NULL;
}
if (irq_err && ih_err) {
if (irq_err && ih_err) {
err = bus_teardown_intr(self, irq_err, ih_err);
if (err)
@ -317,7 +324,7 @@ ehci_mbus_detach(device_t self)
bus_release_resource(self, SYS_RES_IRQ, 0, irq_err);
irq_err = NULL;
}
if (sc->sc_irq_res) {
if (sc->sc_irq_res) {
bus_release_resource(self, SYS_RES_IRQ, 1, sc->sc_irq_res);
sc->sc_irq_res = NULL;
}
@ -359,12 +366,12 @@ err_intr(void *arg)
static device_method_t ehci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ehci_mbus_probe),
DEVMETHOD(device_attach, ehci_mbus_attach),
DEVMETHOD(device_detach, ehci_mbus_detach),
DEVMETHOD(device_suspend, ehci_mbus_suspend),
DEVMETHOD(device_resume, ehci_mbus_resume),
DEVMETHOD(device_shutdown, ehci_mbus_shutdown),
DEVMETHOD(device_probe, mv_ehci_probe),
DEVMETHOD(device_attach, mv_ehci_attach),
DEVMETHOD(device_detach, mv_ehci_detach),
DEVMETHOD(device_suspend, mv_ehci_suspend),
DEVMETHOD(device_resume, mv_ehci_resume),
DEVMETHOD(device_shutdown, mv_ehci_shutdown),
/* Bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
@ -380,5 +387,5 @@ static driver_t ehci_driver = {
static devclass_t ehci_devclass;
DRIVER_MODULE(ehci, mbus, ehci_driver, ehci_devclass, 0, 0);
DRIVER_MODULE(ehci, simplebus, ehci_driver, ehci_devclass, 0, 0);
MODULE_DEPEND(ehci, usb, 1, 1, 1);