From owner-p4-projects@FreeBSD.ORG Thu Jan 28 12:02:52 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id CFEEB1065693; Thu, 28 Jan 2010 12:02:52 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 93CF91065670 for ; Thu, 28 Jan 2010 12:02:52 +0000 (UTC) (envelope-from raj@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 7F7AB8FC1F for ; Thu, 28 Jan 2010 12:02:52 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id o0SC2qYx035947 for ; Thu, 28 Jan 2010 12:02:52 GMT (envelope-from raj@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o0SC2qID035945 for perforce@freebsd.org; Thu, 28 Jan 2010 12:02:52 GMT (envelope-from raj@freebsd.org) Date: Thu, 28 Jan 2010 12:02:52 GMT Message-Id: <201001281202.o0SC2qID035945@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to raj@freebsd.org using -f From: Rafal Jaworowski To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 173827 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 Jan 2010 12:02:53 -0000 http://p4web.freebsd.org/chv.cgi?CH=173827 Change 173827 by raj@raj_fdt on 2010/01/28 12:01:56 Marvell SOC: Initial support for processing Multi-purpose pin (MPP) data and programming the controller, based on config data retrieved from the DTB blob (instead of using hard coded values). Affected files ... .. //depot/projects/fdt/sys/arm/mv/kirkwood/db88f6xxx.c#2 edit .. //depot/projects/fdt/sys/arm/mv/mv_machdep.c#4 edit .. //depot/projects/fdt/sys/arm/mv/mvvar.h#2 edit Differences ... ==== //depot/projects/fdt/sys/arm/mv/kirkwood/db88f6xxx.c#2 (text+ko) ==== @@ -102,47 +102,6 @@ { -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) { ==== //depot/projects/fdt/sys/arm/mv/mv_machdep.c#4 (text+ko) ==== @@ -63,10 +63,13 @@ #include #include #include +#include #include #include +#include #include +#include "../../contrib/dtc/libfdt/libfdt_env.h" #include #include @@ -86,6 +89,7 @@ #include #include +#include /* XXX */ #include /* XXX eventually this should be eliminated */ #include @@ -162,6 +166,7 @@ static void print_bootinfo(void); static void physmap_init(int); +static int platform_mpp_init(void); static char * kenv_next(char *cp) @@ -557,6 +562,14 @@ setttb(kernel_l1pt.pv_pa); cpu_tlb_flushID(); cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)); + + /* + * 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); + cninit(); physmem = memsize / PAGE_SIZE; @@ -569,11 +582,6 @@ print_kenv(); /* - * Re-initialise MPP - */ - platform_mpp_init(); - - /* * Re-initialise decode windows */ if (soc_decode_win() != 0) @@ -649,6 +657,131 @@ 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]; + char buf[64]; + uint32_t ctrl_val, ctrl_offset; + pcell_t reg[4]; + u_long start, size; + phandle_t node; + pcell_t pin_cells, *pinmap_ptr, pin_max; + 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("/aliases")) != 0) + if (OF_getprop(node, "mpp", buf, sizeof(buf)) > 0) { + if ((node = OF_finddevice(buf)) == 0) + return (ENXIO); + if (!fdt_is_compatible(node, "mrvl,mpp")) + return (ENXIO); + goto moveon; + } + + /* + * Find the node the long way. + * TODO + */ + +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_SIMPLEBUS_VA; + + /* + * Process 'pin-max' and 'pin-map' props. + */ + if (OF_getprop(node, "pin-max", &pin_max, sizeof(pin_max)) <= 0) + return (ENXIO); + pin_max = fdt32_to_cpu(pin_max); + if (pin_max > 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_max) + 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_max;) { + ctrl_val = 0; + + for (j = 0; j < MPP_PINS_PER_REG; j++) { + if (i + j == pin_max - 1) + break; + ctrl_val |= MPP_SEL(i + j, mpp[i + j]); + } + i += MPP_PINS_PER_REG; + bus_space_write_4(obio_tag, start, ctrl_offset, ctrl_val); + + /* + * XXX this needs to be worked around for Orion, where MPP + * control regs are not placed linearly. + */ + ctrl_offset += 4; + } + + return (0); +} + struct arm32_dma_range * bus_dma_get_range(void) { ==== //depot/projects/fdt/sys/arm/mv/mvvar.h#2 (text+ko) ==== @@ -129,7 +129,6 @@ void mv_gpio_out(uint32_t pin, uint8_t val, uint8_t enable); uint8_t mv_gpio_in(uint32_t pin); -void platform_mpp_init(void); int soc_decode_win(void); void soc_id(uint32_t *dev, uint32_t *rev); void soc_identify(void);