Date: Mon, 18 Jun 2012 17:50:28 +0000 From: aleek@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r237897 - in soc2012/aleek/beaglexm-armv6/sys: arm/arm arm/conf arm/ti arm/ti/am37x boot/fdt/dts Message-ID: <20120618175028.178F31065670@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: aleek Date: Mon Jun 18 17:50:27 2012 New Revision: 237897 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=237897 Log: prcm driver is done, need to test Modified: soc2012/aleek/beaglexm-armv6/sys/arm/arm/pmap-v6.c soc2012/aleek/beaglexm-armv6/sys/arm/conf/BEAGLEBOARD-XM soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_gptimer.c soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_prcm.c soc2012/aleek/beaglexm-armv6/sys/arm/ti/ti_machdep.c soc2012/aleek/beaglexm-armv6/sys/boot/fdt/dts/beagleboardxm.dts Modified: soc2012/aleek/beaglexm-armv6/sys/arm/arm/pmap-v6.c ============================================================================== --- soc2012/aleek/beaglexm-armv6/sys/arm/arm/pmap-v6.c Mon Jun 18 17:31:44 2012 (r237896) +++ soc2012/aleek/beaglexm-armv6/sys/arm/arm/pmap-v6.c Mon Jun 18 17:50:27 2012 (r237897) @@ -1316,7 +1316,7 @@ rv = 1; } -#ifdef DEBUG +#ifdef DEBUGA /* * If 'rv == 0' at this point, it generally indicates that there is a * stale TLB entry for the faulting address. This happens when two or Modified: soc2012/aleek/beaglexm-armv6/sys/arm/conf/BEAGLEBOARD-XM ============================================================================== --- soc2012/aleek/beaglexm-armv6/sys/arm/conf/BEAGLEBOARD-XM Mon Jun 18 17:31:44 2012 (r237896) +++ soc2012/aleek/beaglexm-armv6/sys/arm/conf/BEAGLEBOARD-XM Mon Jun 18 17:50:27 2012 (r237897) @@ -58,6 +58,7 @@ options WITNESS #Enable checks to detect deadlocks and cycles options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed #options DIAGNOSTIC +options DEBUG # NFS support #options NFSCL Modified: soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_gptimer.c ============================================================================== --- soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_gptimer.c Mon Jun 18 17:31:44 2012 (r237896) +++ soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_gptimer.c Mon Jun 18 17:50:27 2012 (r237897) @@ -52,12 +52,18 @@ #include <machine/resource.h> #include <machine/intr.h> +#include <dev/fdt/fdt_common.h> +#include <dev/ofw/openfirm.h> +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> + +#include <machine/bus.h> +#include <machine/fdt.h> + #include <arm/ti/ti_cpuid.h> #include <arm/ti/ti_prcm.h> #include <arm/ti/am37x/am37x_gptimer.h> - - static struct omap3_gptimer_softc *g_omap3_gptimer_sc = NULL; static unsigned int delay_loops_per_us = 100; @@ -792,9 +798,17 @@ static int omap3_gptimer_probe(device_t dev) { - printf( "GPTIMER HABABABA\n" ); - device_set_desc(dev, "TI OMAP3 General Purpose Timers"); - return (0); + struct omap3_gptimer_softc *sc; + sc = (struct omap3_gptimer_softc *)device_get_softc(dev); + device_printf(dev, "PROBING...\n"); + printf("gptimer: PROBING...\n"); + + if (ofw_bus_is_compatible(dev, "ti,omap3_gptimer")) { + device_set_desc(dev, "OMAP3 General Purpose Timer"); + return(BUS_PROBE_DEFAULT); + } + + return (ENXIO); } static int Modified: soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_prcm.c ============================================================================== --- soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_prcm.c Mon Jun 18 17:31:44 2012 (r237896) +++ soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_prcm.c Mon Jun 18 17:50:27 2012 (r237897) @@ -55,6 +55,7 @@ #include <arm/ti/tivar.h> #include <arm/ti/ti_prcm.h> + #include <arm/ti/am37x/am37x_reg.h> @@ -142,18 +143,19 @@ struct omap3_prcm_softc { struct resource *res[2]; - bus_space_tag_t prm_bst, cm_bst; - bus_space_handle_t prm_bsh, cm_bsh; + bus_space_tag_t prm_bst; + bus_space_handle_t prm_bsh; + bus_space_tag_t cm_bst; + bus_space_handle_t cm_bsh; }; static struct resource_spec omap3_prcm_spec[] = { { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { SYS_RES_MEMORY, 1, RF_ACTIVE | RF_OPTIONAL }, - { SYS_RES_MEMORY, 2, RF_ACTIVE | RF_OPTIONAL }, - { SYS_RES_MEMORY, 3, RF_ACTIVE | RF_OPTIONAL }, + { SYS_RES_MEMORY, 1, RF_ACTIVE }, { -1, 0, 0 } }; + static int omap3_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq); @@ -181,7 +183,17 @@ static int omap3_clk_generic_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq); +static const struct ti_clk_details* +omap3_clk_details(clk_ident_t id); +#define prm_read_4(reg) \ + bus_space_read_4(omap3_prcm_sc->prm_bst, omap3_prcm_sc->prm_bsh, reg) +#define prm_write_4(reg, val) \ + bus_space_write_4(omap3_prcm_sc->prm_bst, omap3_prcm_sc->prm_bsh, reg, val) +#define cm_read_4(reg) \ + bus_space_read_4(omap3_prcm_sc->cm_bst, omap3_prcm_sc->cm_bsh, reg) +#define cm_write_4(reg, val) \ + bus_space_write_4(omap3_prcm_sc->cm_bst, omap3_prcm_sc->cm_bsh, reg, val) @@ -433,27 +445,173 @@ omap3_clk_get_sysclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq) { + uint32_t clksel; + uint32_t clknsel; + unsigned int oscclk; + unsigned int sysclk; + + /* Read the input clock freq from the configuration register */ + + clknsel = prm_read_4(CLOCK_CTRL_PRM_OFFSET + 0x40); + //clknsel = bus_read_4(mem_res[PRM_INSTANCE_MEM_REGION], CLOCK_CTRL_PRM_OFFSET + 0x40); + switch (clknsel & 0x7) { + case 0x0: + /* 12Mhz */ + oscclk = 12000000; + break; + case 0x1: + /* 13Mhz */ + oscclk = 13000000; + break; + case 0x2: + /* 19.2Mhz */ + oscclk = 19200000; + break; + case 0x3: + /* 26Mhz */ + oscclk = 26000000; + break; + case 0x4: + /* 38.4Mhz */ + oscclk = 38400000; + break; + case 0x5: + /* 16.8Mhz */ + oscclk = 16800000; + break; + default: + panic("%s: Invalid clock freq", __func__); + } + + /* Read the value of the clock divider used for the system clock */ + clksel = prm_read_4(CLOCK_CTRL_PRM_OFFSET + 0x70); + //clksel = bus_read_4(mem_res[PRM_INSTANCE_MEM_REGION], GLOBAL_PRM_OFFSET + 0x70); + switch (clksel & 0xC0) { + case 0x40: + sysclk = oscclk; + break; + case 0x80: + sysclk = oscclk / 2; + break; + default: + panic("%s: Invalid system clock divider", __func__); + } + + /* Return the value */ + if (freq) + *freq = sysclk; + return (0); } static int omap3_clk_get_arm_fclk_freq(struct ti_clock_dev *clkdev, unsigned int *freq) { - + unsigned int sysclk; + unsigned int coreclk; + unsigned int mpuclk; + uint32_t clksel; + uint32_t clkout; + + /* Get the SYSCLK freq */ + omap3_clk_get_sysclk_freq(clkdev, &sysclk); + + /* First get the freq of the CORE_CLK (feed from DPLL3) */ + clksel = cm_read_4(CLOCK_CTRL_CM_OFFSET + 0x40); + clkout = (sysclk * ((clksel >> 16) & 0x7FF)) / (((clksel >> 8) & 0x7F) + 1); + coreclk = clkout / (clksel >> 27); + + + /* Next get the freq for the MPU_CLK */ + clksel = cm_read_4(MPU_CM_OFFSET + 0x40); + mpuclk = (coreclk * ((clksel >> 8) & 0x7FF)) / ((clksel & 0x7F) + 1); + + + /* Return the value */ + if (freq) + *freq = mpuclk; + return (0); } static int omap3_clk_generic_activate(struct ti_clock_dev *clkdev) { + const struct ti_clk_details* clk_details = omap3_clk_details(clkdev->id); + uint32_t fclken, iclken; + + if (clk_details == NULL) + return (ENXIO); + + + /* All the 'generic' clocks have a FCLKEN, ICLKEN and IDLEST register which + * is for the functional, interface and clock status regsters respectively. + */ + + /* Enable the interface clock */ + //iclken = cm_read_4(clk_details->iclken_offset); + iclken = + bus_space_read_4( + omap3_prcm_sc->cm_bst, + omap3_prcm_sc->cm_bsh, + clk_details->iclken_offset); + iclken |= (1UL << clk_details->bit_offset); + cm_write_4(clk_details->iclken_offset, iclken); + + /* Read back the value to ensure the write has taken place ... needed ? */ + iclken = cm_read_4(clk_details->iclken_offset); + + + /* Enable the functional clock */ + fclken = cm_read_4( clk_details->fclken_offset); + fclken |= (1UL << clk_details->bit_offset); + cm_write_4(clk_details->fclken_offset, fclken); + + /* Read back the value to ensure the write has taken place ... needed ? */ + fclken = cm_read_4(clk_details->fclken_offset); + + + /* Now poll on the IDLEST register to tell us if the module has come up. + * TODO: We need to take into account the parent clocks. + */ + /* Try MAX_MODULE_ENABLE_WAIT number of times to check if enabled */ +// @TODO XXX trzeba to zrobic +#if 0 + if (omap3_clk_wait_on_reg(clk_mem_res, clk_details->idlest_offset, + (1UL << clk_details->bit_offset), 0) != 0) { + printf("Error: failed to enable module with clock %d\n", clkdev->id); + return (ETIMEDOUT); + } +#endif return (0); } static int omap3_clk_generic_deactivate(struct ti_clock_dev *clkdev) { + const struct ti_clk_details* clk_details = omap3_clk_details(clkdev->id); + uint32_t fclken, iclken; + + if (clk_details == NULL) + return (ENXIO); + + /* All the 'generic' clocks have a FCLKEN, ICLKEN and IDLEST register which + * is for the functional, interface and clock status regsters respectively. + */ + + /* Disable the interface clock */ + iclken = cm_read_4(clk_details->iclken_offset); + iclken &= ~(1UL << clk_details->bit_offset); + cm_write_4(clk_details->iclken_offset, iclken); + + /* Disable the functional clock */ + fclken = cm_read_4(clk_details->fclken_offset); + fclken &= ~(1UL << clk_details->bit_offset); + cm_write_4(clk_details->fclken_offset, fclken); + + return (0); } @@ -467,31 +625,147 @@ static int omap3_clk_generic_accessible(struct ti_clock_dev *clkdev) { + const struct ti_clk_details* clk_details = omap3_clk_details(clkdev->id); + uint32_t idlest; + + if (clk_details == NULL) + return (ENXIO); - return (0); + idlest = cm_read_4(clk_details->idlest_offset); + + /* Check the enabled state */ + if ((idlest & (1UL << clk_details->bit_offset)) == 0) + return (0); + + return (1); } static int omap3_clk_gptimer_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq) { + const struct ti_clk_details* clk_details = omap3_clk_details(clkdev->id); + + if (clk_details == NULL) + return (ENXIO); + /* Simply return the stored frequency */ + if (freq) + *freq = (unsigned int)clk_details->src_freq; + return (0); } static int omap3_clk_gptimer_set_source(struct ti_clock_dev *clkdev, clk_src_t clksrc) { + const struct ti_clk_details* clk_details = omap3_clk_details(clkdev->id); + uint32_t bit, regoff; + uint32_t clksel; + + if (clk_details == NULL) + return (ENXIO); + /* Set the source freq by writing the clksel register */ + switch (clkdev->id) { + case GPTIMER1_CLK: + bit = 0; + regoff = WKUP_CM_OFFSET + 0x40; + break; + case GPTIMER2_CLK ... GPTIMER9_CLK: + bit = (clkdev->id - GPTIMER2_CLK); + regoff = PER_CM_OFFSET + 0x40; + break; + case GPTIMER10_CLK ... GPTIMER11_CLK: + bit = 6 + (clkdev->id - GPTIMER10_CLK); + regoff = CORE_CM_OFFSET + 0x40; + break; + default: + return (EINVAL); + } + + /* Set the CLKSEL bit if then the SYS_CLK is the source */ + clksel = cm_read_4(regoff); + + if (clksrc == SYSCLK_CLK) + clksel |= (0x1UL << bit); + else + clksel &= ~(0x1UL << bit); + + cm_write_4(regoff, clksel); + + /* Read back the value to ensure the write has taken place ... needed ? */ + clksrc = cm_read_4(regoff); + return (0); } static int omap3_clk_generic_get_source_freq(struct ti_clock_dev *clkdev, unsigned int *freq) { + const struct ti_clk_details* clk_details = omap3_clk_details(clkdev->id); + uint32_t bit, regoff; + uint32_t clksel; + unsigned int src_freq; + + if (clk_details == NULL) + return (ENXIO); + /* Determine the source freq by reading the clksel register */ + switch (clkdev->id) { + case GPTIMER1_CLK: + bit = 0; + regoff = WKUP_CM_OFFSET + 0x40; + break; + case GPTIMER2_CLK ... GPTIMER9_CLK: + bit = (clkdev->id - GPTIMER2_CLK); + regoff = PER_CM_OFFSET + 0x40; + break; + case GPTIMER10_CLK ... GPTIMER11_CLK: + bit = 6 + (clkdev->id - GPTIMER10_CLK); + regoff = CORE_CM_OFFSET + 0x40; + break; + default: + return (EINVAL); + } + + + /* If the CLKSEL bit is set then the SYS_CLK is the source */ + clksel = cm_read_4(regoff); + if (clksel & (0x1UL << bit)) + omap3_clk_get_sysclk_freq(NULL, &src_freq); + else + src_freq = FREQ_32KHZ; + + /* Return the frequency */ + if (freq) + *freq = src_freq; + return (0); } +/** + * omap3_clk_details - returns a pointer to the generic clock details + * @id: The ID of the clock to get the details for + * + * This function iterates over the g_omap3_clk_details array and returns a + * pointer to the entry that matches the supplied ID, or NULL if no entry + * is found. + * + * RETURNS: + * Pointer to clock details or NULL on failure + */ +static const struct ti_clk_details* +omap3_clk_details(clk_ident_t id) +{ + const struct ti_clk_details *walker; + + for (walker = g_omap3_clk_details; walker->id != INVALID_CLK_IDENT; walker++) { + if (id == walker->id) + return (walker); + } + + return NULL; +} Modified: soc2012/aleek/beaglexm-armv6/sys/arm/ti/ti_machdep.c ============================================================================== --- soc2012/aleek/beaglexm-armv6/sys/arm/ti/ti_machdep.c Mon Jun 18 17:31:44 2012 (r237896) +++ soc2012/aleek/beaglexm-armv6/sys/arm/ti/ti_machdep.c Mon Jun 18 17:50:27 2012 (r237897) @@ -91,7 +91,6 @@ #include <arm/ti/omap4/omap4_reg.h> #include <arm/ti/am37x/am37x_early_uart.h> -#define DEBUG #ifdef DEBUG #define debugf(fmt, args...) printf(fmt, ##args) #else Modified: soc2012/aleek/beaglexm-armv6/sys/boot/fdt/dts/beagleboardxm.dts ============================================================================== --- soc2012/aleek/beaglexm-armv6/sys/boot/fdt/dts/beagleboardxm.dts Mon Jun 18 17:31:44 2012 (r237896) +++ soc2012/aleek/beaglexm-armv6/sys/boot/fdt/dts/beagleboardxm.dts Mon Jun 18 17:50:27 2012 (r237897) @@ -106,7 +106,7 @@ 0x49040000 0x1000 0x48086000 0x1000 0x48088000 0x1000 >; - interrupts = < 37 38 39 40 41 42 43 44 45 46 47 >; + interrupts = < 37 38 39 40 41 42 43 >; interrupt-parent = <&AINTC>; };
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120618175028.178F31065670>