From owner-p4-projects@FreeBSD.ORG Tue Feb 24 09:53:56 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 8480410656C3; Tue, 24 Feb 2009 09:53:55 +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 353A810656BE for ; Tue, 24 Feb 2009 09:53:55 +0000 (UTC) (envelope-from andrew@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 2282A8FC18 for ; Tue, 24 Feb 2009 09:53:55 +0000 (UTC) (envelope-from andrew@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n1O9rtaT039272 for ; Tue, 24 Feb 2009 09:53:55 GMT (envelope-from andrew@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n1O9rtCu039270 for perforce@freebsd.org; Tue, 24 Feb 2009 09:53:55 GMT (envelope-from andrew@freebsd.org) Date: Tue, 24 Feb 2009 09:53:55 GMT Message-Id: <200902240953.n1O9rtCu039270@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to andrew@freebsd.org using -f From: Andrew Turner To: Perforce Change Reviews Cc: Subject: PERFORCE change 158191 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Feb 2009 09:53:58 -0000 http://perforce.freebsd.org/chv.cgi?CH=158191 Change 158191 by andrew@andrew_bender on 2009/02/24 09:53:24 Correctly calculate the clock speeds on s3c244x Fix the console so it will only appear on the uart the kernel sends it's output to. Support the UART in both s3c241x and s3c244x. Affected files ... .. //depot/projects/arm/src/sys/arm/s3c2xx0/s3c2440reg.h#1 add .. //depot/projects/arm/src/sys/arm/s3c2xx0/s3c24x0.c#9 edit .. //depot/projects/arm/src/sys/arm/s3c2xx0/s3c24x0_machdep.c#5 edit .. //depot/projects/arm/src/sys/arm/s3c2xx0/s3c24x0reg.h#4 edit .. //depot/projects/arm/src/sys/arm/s3c2xx0/s3c24x0var.h#4 edit .. //depot/projects/arm/src/sys/arm/s3c2xx0/uart_bus_s3c2410.c#5 edit .. //depot/projects/arm/src/sys/arm/s3c2xx0/uart_dev_s3c2410.c#11 edit Differences ... ==== //depot/projects/arm/src/sys/arm/s3c2xx0/s3c24x0.c#9 (text+ko) ==== @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -334,6 +335,11 @@ S3C24X0_TIMER_SIZE, 0, &sc->sc_timer_ioh)) panic("cannot map TIMER"); + /* + * Identify the CPU + */ + s3c24x0_identify_cpu(dev); + /* calculate current clock frequency */ s3c24x0_clock_freq(&sc->sc_sx); printf(": fclk %d MHz hclk %d MHz pclk %d MHz", @@ -342,11 +348,6 @@ printf("\n"); /* - * Identify the CPU - */ - s3c24x0_identify_cpu(dev); - - /* * Attach children devices */ s3c2xx0_softc->s3c2xx0_irq_rman.rm_type = RMAN_ARRAY; @@ -373,7 +374,7 @@ S3C2410_SDI_SIZE); /* Add the uart and set it's irq and registers */ - for (i = 0; i < 1; i++) { + for (i = 0; i < 3; i++) { child = s3c24x0_add_child(dev, 0, "uart", i); irq = 0; @@ -425,11 +426,11 @@ /* * fill sc_pclk, sc_hclk, sc_fclk from values of clock controller register. * - * s3c24x0_clock_freq2() is meant to be called from kernel startup routines. + * s3c24{1,4}0_clock_freq2() is meant to be called from kernel startup routines. * s3c24x0_clock_freq() is for after kernel initialization is done. */ void -s3c24x0_clock_freq2(vm_offset_t clkman_base, int *fclk, int *hclk, int *pclk) +s3c2410_clock_freq2(vm_offset_t clkman_base, int *fclk, int *hclk, int *pclk) { uint32_t pllcon, divn; int mdiv, pdiv, sdiv; @@ -444,7 +445,7 @@ f = ((mdiv + 8) * S3C2XX0_XTAL_CLK) / ((pdiv + 2) * (1 << sdiv)); h = f; - if (divn & CLKDIVN_HDIVN) + if (divn & S3C2410_CLKDIVN_HDIVN) h /= 2; p = h; if (divn & CLKDIVN_PDIVN) @@ -453,7 +454,53 @@ if (fclk) *fclk = f; if (hclk) *hclk = h; if (pclk) *pclk = p; +} + +void +s3c2440_clock_freq2(vm_offset_t clkman_base, int *fclk, int *hclk, int *pclk) +{ + uint32_t pllcon, divn, camdivn; + int mdiv, pdiv, sdiv; + int f, h, p; + + pllcon = *(volatile uint32_t *)(clkman_base + CLKMAN_MPLLCON); + divn = *(volatile uint32_t *)(clkman_base + CLKMAN_CLKDIVN); + camdivn = *(volatile uint32_t *)(clkman_base + S3C2440_CLKMAN_CAMDIVN); + + mdiv = (pllcon & PLLCON_MDIV_MASK) >> PLLCON_MDIV_SHIFT; + pdiv = (pllcon & PLLCON_PDIV_MASK) >> PLLCON_PDIV_SHIFT; + sdiv = (pllcon & PLLCON_SDIV_MASK) >> PLLCON_SDIV_SHIFT; + + f = (2 * (mdiv + 8) * S3C2XX0_XTAL_CLK) / ((pdiv + 2) * (1 << sdiv)); + h = f; + switch((divn >> 1) & 3) { + case 0: + break; + case 1: + h /= 2; + break; + case 2: + if ((camdivn & S3C2440_CAMDIVN_HCLK4_HALF) == + S3C2440_CAMDIVN_HCLK4_HALF) + h /= 8; + else + h /= 4; + break; + case 3: + if ((camdivn & S3C2440_CAMDIVN_HCLK3_HALF) == + S3C2440_CAMDIVN_HCLK3_HALF) + h /= 6; + else + h /= 3; + break; + } + p = h; + if (divn & CLKDIVN_PDIVN) + p /= 2; + if (fclk) *fclk = f; + if (hclk) *hclk = h; + if (pclk) *pclk = p; } void @@ -462,7 +509,16 @@ vm_offset_t va; va = sc->sc_clkman_ioh; - s3c24x0_clock_freq2(va, &sc->sc_fclk, &sc->sc_hclk, &sc->sc_pclk); + switch(sc->sc_cpu) { + case CPU_S3C2410: + s3c2410_clock_freq2(va, &sc->sc_fclk, &sc->sc_hclk, + &sc->sc_pclk); + break; + case CPU_S3C2440: + s3c2440_clock_freq2(va, &sc->sc_fclk, &sc->sc_hclk, + &sc->sc_pclk); + break; + } } void ==== //depot/projects/arm/src/sys/arm/s3c2xx0/s3c24x0_machdep.c#5 (text+ko) ==== @@ -149,36 +149,34 @@ * with the MMU on or off. */ { - /* - * Map the IRQ Controller - */ - _A(S3C24X0_INTCTL_BASE), - _A(S3C24X0_INTCTL_BASE), - _S(S3C24X0_INTCTL_SIZE), + _A(S3C24X0_CLKMAN_BASE), + _A(S3C24X0_CLKMAN_BASE), + _S(S3C24X0_CLKMAN_SIZE), VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, { - _A(S3C24X0_CLKMAN_BASE), - _A(S3C24X0_CLKMAN_BASE), - _S(S3C24X0_CLKMAN_SIZE), - VM_PROT_READ|VM_PROT_WRITE, + _A(S3C24X0_GPIO_BASE), + _A(S3C24X0_GPIO_BASE), + _S(S3C2410_GPIO_SIZE), + VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, { - /* - * Map the UART to VA == PA - */ - _A(S3C24X0_UART0_BASE), - _A(S3C24X0_UART0_BASE), - _S(S3C24X0_UART_BASE(3) - S3C24X0_UART0_BASE), + _A(S3C24X0_IIC_BASE), + _A(S3C24X0_IIC_BASE), + _S(S3C24X0_IIC_SIZE), VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, { - /* - * Map the LCD to VA == PA - */ + _A(S3C24X0_INTCTL_BASE), + _A(S3C24X0_INTCTL_BASE), + _S(S3C24X0_INTCTL_SIZE), + VM_PROT_READ|VM_PROT_WRITE, + PTE_NOCACHE, + }, + { _A(S3C24X0_LCDC_BASE), _A(S3C24X0_LCDC_BASE), _S(S3C24X0_LCDC_SIZE), @@ -186,9 +184,6 @@ PTE_NOCACHE, }, { - /* - * Map the MMC/SD to VA == PA - */ _A(S3C24X0_SDI_BASE), _A(S3C24X0_SDI_BASE), _S(S3C2410_SDI_SIZE), @@ -196,12 +191,9 @@ PTE_NOCACHE, }, { - /* - * Map the IIC to VA == PA - */ - _A(S3C24X0_IIC_BASE), - _A(S3C24X0_IIC_BASE), - _S(S3C24X0_IIC_SIZE), + _A(S3C24X0_UART0_BASE), + _A(S3C24X0_UART0_BASE), + _S(S3C24X0_UART_BASE(3) - S3C24X0_UART0_BASE), VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, @@ -217,6 +209,7 @@ #undef _A #undef _S +#define ioreg_read32(a) (*(volatile uint32_t *)(a)) #define ioreg_write32(a,v) (*(volatile uint32_t *)(a)=(v)) #ifdef DDB @@ -389,7 +382,16 @@ ioreg_write32(S3C24X0_INTCTL_BASE + INTCTL_INTMSK, ~0); memsize = board_init(); /* Find pclk for uart */ - s3c24x0_clock_freq2(S3C24X0_CLKMAN_BASE, NULL, NULL, &s3c2410_pclk); + switch(ioreg_read32(S3C24X0_GPIO_BASE + GPIO_GSTATUS1) >> 16) { + case 0x3241: + s3c2410_clock_freq2(S3C24X0_CLKMAN_BASE, NULL, NULL, + &s3c2410_pclk); + break; + case 0x3244: + s3c2440_clock_freq2(S3C24X0_CLKMAN_BASE, NULL, NULL, + &s3c2410_pclk); + break; + } cninit(); /* Set stack for exception handlers */ ==== //depot/projects/arm/src/sys/arm/s3c2xx0/s3c24x0reg.h#4 (text+ko) ==== @@ -230,7 +230,6 @@ #define CLKSLOW_VAL_MASK 0x0f /* divider value for slow clock */ #define CLKMAN_CLKDIVN 0x14 /* Software reset control */ -#define CLKDIVN_HDIVN (1<<1) #define CLKDIVN_PDIVN (1<<0) #define S3C24X0_CLKMAN_SIZE 0x18 ==== //depot/projects/arm/src/sys/arm/s3c2xx0/s3c24x0var.h#4 (text+ko) ==== @@ -42,7 +42,8 @@ }; void s3c24x0_clock_freq(struct s3c2xx0_softc *); -void s3c24x0_clock_freq2(vm_offset_t, int *, int *, int *); +void s3c2410_clock_freq2(vm_offset_t, int *, int *, int *); +void s3c2440_clock_freq2(vm_offset_t, int *, int *, int *); void s3c24x0_sleep(int); ==== //depot/projects/arm/src/sys/arm/s3c2xx0/uart_bus_s3c2410.c#5 (text+ko) ==== @@ -15,6 +15,8 @@ #include #include +#include + #include "uart_if.h" static int uart_s3c2410_probe(device_t dev); @@ -38,14 +40,20 @@ static int uart_s3c2410_probe(device_t dev) { + struct uart_devinfo *sysdev; struct uart_softc *sc; + int unit; sc = device_get_softc(dev); - sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); sc->sc_class = &uart_s3c2410_class; - bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); - return(uart_bus_probe(dev, 0, 0, 0, 0)); - return (0); + + unit = device_get_unit(dev); + sysdev = SLIST_FIRST(&uart_sysdevs); + if (S3C24X0_UART_BASE(unit) == sysdev->bas.bsh) { + sc->sc_sysdev = sysdev; + bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); + } + return(uart_bus_probe(dev, 0, 0, 0, unit)); } DRIVER_MODULE(uart, s3c24x0, uart_s3c2410_driver, uart_devclass, 0, 0); ==== //depot/projects/arm/src/sys/arm/s3c2xx0/uart_dev_s3c2410.c#11 (text+ko) ==== @@ -41,9 +41,10 @@ #include #include #include -#include +#include #include #include +#include #include "uart_if.h" /* Finds the subirq from the parent */ @@ -240,14 +241,19 @@ { uintptr_t irq; - bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); - - /* - * TODO: The S3C2410 has a 16 byte fifo, the s3c2440 has a - * 64 byte fifo. figure out which CPU we are on to set this - */ - sc->sc_txfifosz = 16; - sc->sc_rxfifosz = 16; + switch(s3c2xx0_softc->sc_cpu) { + case CPU_S3C2410: + sc->sc_txfifosz = 16; + sc->sc_rxfifosz = 16; + break; + case CPU_S3C2440: + sc->sc_txfifosz = 64; + sc->sc_rxfifosz = 64; + break; + default: + return (ENXIO); + } + sc->sc_hwiflow = 0; sc->sc_hwoflow = 0; @@ -256,6 +262,7 @@ arm_unmask_irq(get_sub_irq(irq, RX_OFF)); arm_unmask_irq(get_sub_irq(irq, TX_OFF)); arm_unmask_irq(get_sub_irq(irq, ERR_OFF)); + return (0); } @@ -316,22 +323,32 @@ static int s3c2410_bus_ipend(struct uart_softc *sc) { + uint32_t ufstat, txmask, rxmask; uintptr_t irq; - uint32_t ufstat; int ipend = 0; uart_lock(sc->sc_hwmtx); ufstat = bus_space_read_4(sc->sc_bas.bst, sc->sc_bas.bsh, SSCOM_UFSTAT); uart_unlock(sc->sc_hwmtx); - /* XXX: The register values are incorrect on the s3c244x */ - if ((ufstat & UFSTAT_TXCOUNT) == 0) { + txmask = rxmask = 0; + switch (s3c2xx0_softc->sc_cpu) { + case CPU_S3C2410: + txmask = UFSTAT_TXCOUNT; + rxmask = UFSTAT_RXCOUNT; + break; + case CPU_S3C2440: + txmask = S3C2440_UFSTAT_TXCOUNT; + rxmask = S3C2440_UFSTAT_RXCOUNT; + break; + } + if ((ufstat & txmask) == 0) { if (sc->sc_txbusy != 0) ipend |= SER_INT_TXIDLE; irq = rman_get_start(sc->sc_ires); arm_mask_irq(get_sub_irq(irq, TX_OFF)); } - if ((ufstat & UFSTAT_RXCOUNT) > 0) { + if ((ufstat & rxmask) > 0) { ipend |= SER_INT_RXREADY; }