├── README.md ├── beaglebone-black ├── KERNEL │ ├── arch │ │ └── arm │ │ │ └── boot │ │ │ └── dts │ │ │ ├── am335x-bone-logibone-r1.dtsi │ │ │ └── am335x-boneblack-logibone-r1.dts │ ├── drivers │ │ └── misc │ │ │ ├── Kconfig │ │ │ ├── Makefile │ │ │ └── cape_logibone │ │ │ ├── .ioctl.o.cmd │ │ │ ├── .main_dma.o.cmd │ │ │ ├── .tmp_ioctl.dwo │ │ │ ├── .tmp_main_dma.dwo │ │ │ ├── Kconfig │ │ │ ├── Makefile │ │ │ ├── config.c │ │ │ ├── config.h │ │ │ ├── drvr.h │ │ │ ├── generic.h │ │ │ ├── ioctl.c │ │ │ ├── ioctl.h │ │ │ ├── logi_dma.c │ │ │ ├── logi_dma.h │ │ │ └── main_dma.c │ └── firmware │ │ └── capes │ │ └── BB-BONE-LOGIBONE-00R1.dts ├── bbb_quick_setup.txt ├── build_module.sh ├── cape_eeprom │ ├── data.eeprom │ ├── init_eeprom.sh │ └── mk_logibone_eeprom.c ├── common │ ├── drvr.h │ ├── logi_dma.c │ ├── logi_dma.h │ ├── main_dm.c │ └── main_dma.c ├── logibone_r1 │ ├── BB-BONE-LOGIBONE-00R1.dts │ ├── Makefile │ ├── config.c │ ├── config.h │ ├── generic.h │ ├── ioctl.c │ ├── ioctl.h │ └── setup_device-tree_R1.sh └── logibone_ra2 │ ├── BB-BONE-LOGIBONE-00A3.dts │ ├── BB-BONE-LOGIBONE-00A3_async.dts │ ├── Makefile │ ├── config.c │ ├── config.h │ ├── generic.h │ ├── ioctl.c │ ├── ioctl.h │ └── setup_device-tree_RA2.sh └── old ├── beaglebone-black └── logibone_ra1 │ ├── BB-BONE-LOGIBONE-00A1.dts │ ├── Makefile │ ├── logibone_ra1.c │ ├── logibone_ra1_dm.c │ └── setup_device-tree_RA1.sh ├── beaglebone └── modules │ ├── edma_fifo_module │ ├── Makefile │ ├── build_module.sh │ ├── hw_cm_per.h │ ├── hw_gpmc.h │ ├── logibone_edma_fifo.c │ ├── logibone_edma_fifo.c~ │ ├── logibone_edma_fifo.mod.c │ └── soc_AM335x.h │ └── fifo_module │ ├── Makefile │ ├── build_module.sh │ ├── hw_cm_per.h │ ├── hw_gpmc.h │ ├── logibone_fifo.c │ └── soc_AM335x.h └── mark1 ├── BB-BONE-MARK1-00A1.dts ├── BB-BONE-MARK1-00A1_sync.dts ├── Makefile ├── config.c ├── config.h ├── generic.h ├── ioctl.c ├── ioctl.h └── setup_device-tree_mark1.sh /README.md: -------------------------------------------------------------------------------- 1 | Logi-kernel 2 | =========== 3 | 4 | Linux-kernel related code (patch form mark1/logibone support, kernel modules for communication, etc), can link to supported repositories 5 | 6 | The following kernels have been tested successfully: 7 | 8 | * 4.1.x-bone 9 | * 4.8.x-bone 10 | * 4.1.x-ti 11 | * 4.4.x-ti 12 | * 4.9.x-ti 13 | -------------------------------------------------------------------------------- /beaglebone-black/KERNEL/arch/arm/boot/dts/am335x-bone-logibone-r1.dtsi: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | */ 8 | 9 | 10 | &i2c1 { 11 | pinctrl-names = "default"; 12 | pinctrl-0 = <&i2c1_pins>; 13 | 14 | status = "okay"; 15 | clock-frequency = <100000>; 16 | 17 | pca9534@24 { 18 | compatible = "pca9534"; 19 | reg = <0x24>; 20 | }; 21 | }; 22 | 23 | &am33xx_pinmux { 24 | pinctrl-names = "default"; 25 | 26 | gpmc_pins: pinmux_gpmc_pins { 27 | pinctrl-single,pins = < 28 | 0x000 0x30 /* gpmc_ad0.gpmc_ad0 MODE0 | INPUT | PULLUP */ 29 | 0x004 0x30 /* gpmc_ad1.gpmc_ad1 MODE0 | INPUT | PULLUP */ 30 | 0x008 0x30 /* gpmc_ad2.gpmc_ad2 MODE0 | INPUT | PULLUP */ 31 | 0x00C 0x30 /* gpmc_ad3.gpmc_ad3 MODE0 | INPUT | PULLUP */ 32 | 0x010 0x30 /* gpmc_ad4.gpmc_ad4 MODE0 | INPUT | PULLUP */ 33 | 0x014 0x30 /* gpmc_ad5.gpmc_ad5 MODE0 | INPUT | PULLUP */ 34 | 0x018 0x30 /* gpmc_ad6.gpmc_ad6 MODE0 | INPUT | PULLUP */ 35 | 0x01C 0x30 /* gpmc_ad7.gpmc_ad7 MODE0 | INPUT | PULLUP */ 36 | 0x020 0x30 /* gpmc_ad8.gpmc_ad8 MODE0 | INPUT | PULLUP */ 37 | 0x024 0x30 /* gpmc_ad9.gpmc_ad9 MODE0 | INPUT | PULLUP */ 38 | 0x028 0x30 /* gpmc_ad10.gpmc_ad10 MODE0 | INPUT | PULLUP */ 39 | 0x02C 0x30 /* gpmc_ad11.gpmc_ad11 MODE0 | INPUT | PULLUP */ 40 | 0x030 0x30 /* gpmc_ad12.gpmc_ad12 MODE0 | INPUT | PULLUP */ 41 | 0x034 0x30 /* gpmc_ad13.gpmc_ad13 MODE0 | INPUT | PULLUP */ 42 | 0x038 0x30 /* gpmc_ad14.gpmc_ad14 MODE0 | INPUT | PULLUP */ 43 | 0x03C 0x30 /* gpmc_ad15.gpmc_ad15 MODE0 | INPUT | PULLUP */ 44 | 0x080 0x08 /* gpmc_cscn1.gpmc_cscn1 MODE0 | OUTPUT */ 45 | 0x08C 0x28 /* gpmc_clk.gpmc_clk MODE0 | INPUT */ 46 | 0x090 0x08 /* gpmc_advn_ale.gpmc_advn_ale MODE0 | OUTPUT */ 47 | 0x094 0x08 /* gpmc_oen_ren.gpmc_oen_ren MODE0 | OUTPUT */ 48 | 0x098 0x08 /* gpmc_wen.gpmc_wen MODE0 | OUTPUT */ 49 | 0x09C 0x08 /* gpmc_ben0_cle.gpmc_ben0_cle MODE0 | OUTPUT */ 50 | 0x078 0x08 /* gpmc_ben1_cle.gpmc_ben1_cle MODE0 | OUTPUT */ 51 | >; 52 | }; 53 | }; 54 | 55 | &gpmc{ 56 | depth = <1>; /* only create devices on depth 1 */ 57 | status = "okay"; 58 | 59 | #address-cells = <2>; 60 | #size-cells = <1>; 61 | 62 | pinctrl-names = "default"; 63 | pinctrl-0 = <&gpmc_pins>; 64 | 65 | /* chip select ranges */ 66 | ranges = <1 0 0x01000000 0x1000000>; 67 | 68 | nor { 69 | compatible = "logibone_ra1"; 70 | status = "okay"; 71 | pinctrl-names = "default"; 72 | 73 | /* reset = <&rstctl 0 0>; */ /* uncomment for use under Kernel 3.8.13 */ 74 | /* reset-names = "eMMC_RSTn-LOGIBONE"; *//* uncomment for use under Kernel 3.8.13 */ 75 | 76 | reg = <1 0 0x01000000>; /*CSn1*/ 77 | 78 | /* CONFIG1 */ 79 | bank-width = <2>; /* GPMC_CONFIG1_DEVICESIZE(1) */ 80 | /*gpmc,burst-write;*/ 81 | /*gpmc,burst-read;*/ 82 | /*gpmc,burst-wrap;*/ 83 | gpmc,sync-read; /* GPMC_CONFIG1_READTYPE_ASYNC */ 84 | gpmc,sync-write; /* GPMC_CONFIG1_WRITETYPE_ASYNC */ 85 | gpmc,clk-activation-ns = <0>; /* GPMC_CONFIG1_CLKACTIVATIONTIME(2) */ 86 | gpmc,burst-length = <16>; /* GPMC_CONFIG1_PAGE_LEN(2) */ 87 | gpmc,mux-add-data = <2>; /* GPMC_CONFIG1_MUXTYPE(2) */ 88 | 89 | /* CONFIG2 */ 90 | gpmc,sync-clk-ps = <20000>; 91 | gpmc,cs-on-ns = <0>; 92 | gpmc,cs-rd-off-ns = <100>; 93 | gpmc,cs-wr-off-ns = <40>; 94 | 95 | /* CONFIG3 */ 96 | gpmc,adv-on-ns = <0>; 97 | gpmc,adv-rd-off-ns = <20>; 98 | gpmc,adv-wr-off-ns = <20>; 99 | 100 | /* CONFIG4 */ 101 | gpmc,we-on-ns = <20>; 102 | gpmc,we-off-ns = <40>; 103 | gpmc,oe-on-ns = <20>; 104 | gpmc,oe-off-ns = <100>; 105 | 106 | /* CONFIG 5 */ 107 | gpmc,page-burst-access-ns = <20>; 108 | gpmc,access-ns = <80>; 109 | gpmc,rd-cycle-ns = <120>; 110 | gpmc,wr-cycle-ns = <60>; 111 | 112 | /* CONFIG 6 */ 113 | gpmc,wr-access-ns = <40>; 114 | gpmc,wr-data-mux-bus-ns = <20>; 115 | /*gpmc,bus-turnaround-ns = <40>;*/ /* CONFIG6:3:0 = 4 */ 116 | /*gpmc,cycle2cycle-samecsen;*/ /* CONFIG6:7 = 1 */ 117 | /*gpmc,cycle2cycle-delay-ns = <40>;*/ /* CONFIG6:11:8 = 4 */ 118 | 119 | /* not using dma engine yet, but we can get the channel number here */ 120 | dmas = <&edma 20>; 121 | dma-names = "logibone"; 122 | 123 | }; 124 | }; 125 | 126 | -------------------------------------------------------------------------------- /beaglebone-black/KERNEL/arch/arm/boot/dts/am335x-boneblack-logibone-r1.dts: -------------------------------------------------------------------------------- 1 | /dts-v1/; 2 | 3 | #include "am33xx.dtsi" 4 | #include "am335x-bone-common.dtsi" 5 | #include "am335x-bone-common-pinmux.dtsi" 6 | 7 | / { 8 | model = "TI AM335x BeagleBone"; 9 | compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; 10 | }; 11 | 12 | &ldo3_reg { 13 | regulator-min-microvolt = <1800000>; 14 | regulator-max-microvolt = <1800000>; 15 | regulator-always-on; 16 | }; 17 | 18 | &mmc1 { 19 | vmmc-supply = <&vmmcsd_fixed>; 20 | }; 21 | 22 | &am33xx_pinmux { 23 | pinctrl-names = "default"; 24 | pinctrl-0 = <&clkout2_pin>; 25 | }; 26 | 27 | #include "am335x-boneblack-nxp-hdmi-no-audio.dtsi" 28 | #include "am335x-bone-logibone-r1.dtsi" 29 | #include "am335x-bone-spi1-spidev.dtsi" 30 | #include "am335x-bone-emmc-in-reset.dtsi" 31 | -------------------------------------------------------------------------------- /beaglebone-black/KERNEL/drivers/misc/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile for misc devices that really don't fit anywhere else. 3 | # 4 | 5 | obj-$(CONFIG_IBM_ASM) += ibmasm/ 6 | obj-$(CONFIG_AD525X_DPOT) += ad525x_dpot.o 7 | obj-$(CONFIG_AD525X_DPOT_I2C) += ad525x_dpot-i2c.o 8 | obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o 9 | obj-$(CONFIG_INTEL_MID_PTI) += pti.o 10 | obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o 11 | obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o 12 | obj-$(CONFIG_BMP085) += bmp085.o 13 | obj-$(CONFIG_BMP085_I2C) += bmp085-i2c.o 14 | obj-$(CONFIG_BMP085_SPI) += bmp085-spi.o 15 | obj-$(CONFIG_DUMMY_IRQ) += dummy-irq.o 16 | obj-$(CONFIG_ICS932S401) += ics932s401.o 17 | obj-$(CONFIG_LKDTM) += lkdtm.o 18 | obj-$(CONFIG_TIFM_CORE) += tifm_core.o 19 | obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o 20 | obj-$(CONFIG_PHANTOM) += phantom.o 21 | obj-$(CONFIG_QCOM_COINCELL) += qcom-coincell.o 22 | obj-$(CONFIG_SENSORS_BH1780) += bh1780gli.o 23 | obj-$(CONFIG_SENSORS_BH1770) += bh1770glc.o 24 | obj-$(CONFIG_SENSORS_APDS990X) += apds990x.o 25 | obj-$(CONFIG_SGI_IOC4) += ioc4.o 26 | obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o 27 | obj-$(CONFIG_KGDB_TESTS) += kgdbts.o 28 | obj-$(CONFIG_SGI_XP) += sgi-xp/ 29 | obj-$(CONFIG_SGI_GRU) += sgi-gru/ 30 | obj-$(CONFIG_CS5535_MFGPT) += cs5535-mfgpt.o 31 | obj-$(CONFIG_HP_ILO) += hpilo.o 32 | obj-$(CONFIG_APDS9802ALS) += apds9802als.o 33 | obj-$(CONFIG_ISL29003) += isl29003.o 34 | obj-$(CONFIG_ISL29020) += isl29020.o 35 | obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o 36 | obj-$(CONFIG_DS1682) += ds1682.o 37 | obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o 38 | obj-$(CONFIG_C2PORT) += c2port/ 39 | obj-$(CONFIG_HMC6352) += hmc6352.o 40 | obj-y += eeprom/ 41 | obj-y += cb710/ 42 | obj-$(CONFIG_HWLAT_DETECTOR) += hwlat_detector.o 43 | obj-$(CONFIG_SPEAR13XX_PCIE_GADGET) += spear13xx_pcie_gadget.o 44 | obj-$(CONFIG_VMWARE_BALLOON) += vmw_balloon.o 45 | obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o 46 | obj-$(CONFIG_PCH_PHUB) += pch_phub.o 47 | obj-y += ti-st/ 48 | obj-y += lis3lv02d/ 49 | obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o 50 | obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ 51 | obj-$(CONFIG_INTEL_MEI) += mei/ 52 | obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/ 53 | obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o 54 | obj-$(CONFIG_SRAM) += sram.o 55 | obj-y += mic/ 56 | obj-y += cape_bone_argus/ 57 | obj-$(CONFIG_GENWQE) += genwqe/ 58 | obj-y += cape/ 59 | obj-$(CONFIG_ECHO) += echo/ 60 | obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o 61 | obj-$(CONFIG_CXL_BASE) += cxl/ 62 | obj-$(CONFIG_TIEQEP) += tieqep.o 63 | obj-$(CONFIG_BONE_CAPEMGR) += bone_capemgr.o 64 | obj-$(CONFIG_DEV_OVERLAYMGR) += devovmgr.o 65 | obj-y += cape_logibone/ 66 | -------------------------------------------------------------------------------- /beaglebone-black/KERNEL/drivers/misc/cape_logibone/.tmp_ioctl.dwo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fpga-logi/logi-kernel/4e22565f4b42ce955945ed986a642f5e7486b2f4/beaglebone-black/KERNEL/drivers/misc/cape_logibone/.tmp_ioctl.dwo -------------------------------------------------------------------------------- /beaglebone-black/KERNEL/drivers/misc/cape_logibone/.tmp_main_dma.dwo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fpga-logi/logi-kernel/4e22565f4b42ce955945ed986a642f5e7486b2f4/beaglebone-black/KERNEL/drivers/misc/cape_logibone/.tmp_main_dma.dwo -------------------------------------------------------------------------------- /beaglebone-black/KERNEL/drivers/misc/cape_logibone/Kconfig: -------------------------------------------------------------------------------- 1 | config CAPE_LOGIBONE_R1 2 | tristate "Beaglebone Logibone Cape" 3 | default n 4 | help 5 | Say Y here to include support for the Logibone Cape 6 | -------------------------------------------------------------------------------- /beaglebone-black/KERNEL/drivers/misc/cape_logibone/Makefile: -------------------------------------------------------------------------------- 1 | obj-$(CONFIG_CAPE_LOGIBONE_R1) += logibone_r1_dma.o 2 | logibone_r1_dma-objs := main_dma.o logi_dma.o ioctl.o 3 | -------------------------------------------------------------------------------- /beaglebone-black/KERNEL/drivers/misc/cape_logibone/config.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "generic.h" 7 | #include "../common/drvr.h" 8 | 9 | 10 | //SSI 11 | #define SSI_CLK 110 12 | #define SSI_DATA 112 13 | #define SSI_DONE 3 14 | #define SSI_PROG 5 15 | #define SSI_INIT 2 16 | #define MODE0 0 17 | #define MODE1 1 18 | #define SSI_DELAY 1 19 | 20 | //GPIO 21 | #define GPIO3_BASE 0x481AE000 22 | #define GPIO3_SETDATAOUT *(gpio_regs+1) 23 | #define GPIO3_CLEARDATAOUT *(gpio_regs) 24 | 25 | //I2C 26 | #define I2C_IO_EXP_CONFIG_REG 0x03 27 | #define I2C_IO_EXP_IN_REG 0x00 28 | #define I2C_IO_EXP_OUT_REG 0x01 29 | 30 | 31 | volatile unsigned * gpio_regs; 32 | 33 | 34 | static inline void __delay_cycles(unsigned long cycles) 35 | { 36 | while (cycles != 0) { 37 | cycles--; 38 | } 39 | } 40 | 41 | static inline void ssiSetClk(void) 42 | { 43 | //gpio_set_value(SSI_CLK, 1); 44 | GPIO3_SETDATAOUT = (1 << 14); 45 | } 46 | 47 | static inline void ssiClearClk(void) 48 | { 49 | //gpio_set_value(SSI_CLK, 0); 50 | GPIO3_CLEARDATAOUT = (1 << 14); 51 | } 52 | 53 | static inline void ssiSetData(void) 54 | { 55 | //gpio_set_value(SSI_DATA, 1); 56 | GPIO3_SETDATAOUT = (1 << 16); 57 | } 58 | 59 | static inline void ssiClearData(void) 60 | { 61 | //gpio_set_value(SSI_DATA, 0); 62 | GPIO3_CLEARDATAOUT = (1 << 16); 63 | } 64 | 65 | static inline void serialConfigWriteByte(unsigned char val) 66 | { 67 | unsigned char bitCount = 0; 68 | unsigned char valBuf = val; 69 | 70 | for (bitCount = 0; bitCount < 8; bitCount++) { 71 | ssiClearClk(); 72 | 73 | if ((valBuf & 0x80) != 0) { 74 | ssiSetData(); 75 | } else { 76 | ssiClearData(); 77 | } 78 | 79 | //__delay_cycles(SSI_DELAY); 80 | ssiSetClk(); 81 | valBuf = (valBuf << 1); 82 | //__delay_cycles(SSI_DELAY); 83 | } 84 | } 85 | 86 | static inline void i2c_set_pin(struct i2c_client * io_cli, unsigned char pin, unsigned char val) 87 | { 88 | unsigned char i2c_buffer[2]; 89 | 90 | i2c_buffer[0] = I2C_IO_EXP_OUT_REG; 91 | i2c_master_send(io_cli, i2c_buffer, 1); 92 | i2c_master_recv(io_cli, &i2c_buffer[1], 1); 93 | 94 | if (val == 1) { 95 | i2c_buffer[1] |= (1 << pin); 96 | } else { 97 | i2c_buffer[1] &= ~(1 << pin); 98 | } 99 | 100 | i2c_master_send(io_cli, i2c_buffer, 2); 101 | } 102 | 103 | static inline unsigned char i2c_get_pin(struct i2c_client * io_cli, unsigned char pin) 104 | { 105 | unsigned char i2c_buffer; 106 | 107 | i2c_buffer = I2C_IO_EXP_IN_REG; 108 | i2c_master_send(io_cli, &i2c_buffer, 1); 109 | i2c_master_recv(io_cli, &i2c_buffer, 1); 110 | 111 | return ((i2c_buffer >> pin) & 0x01); 112 | } 113 | 114 | int loadBitFile(struct i2c_client * io_cli, const unsigned char * bitBuffer_user, const unsigned int length) 115 | { 116 | int res; 117 | unsigned long int i; 118 | unsigned long int timer = 0; 119 | unsigned char * bitBuffer; 120 | unsigned char i2c_buffer[4]; 121 | 122 | //request_mem_region(GPIO3_BASE + 0x190, 8, gDrvrName); 123 | gpio_regs = ioremap_nocache(GPIO3_BASE + 0x190, 2 * sizeof(int)); 124 | 125 | bitBuffer = kmalloc(length, GFP_KERNEL); 126 | 127 | if (bitBuffer == NULL) { 128 | DBG_LOG("Failed allocate buffer for configuration file\n"); 129 | 130 | return -ENOMEM; 131 | } 132 | 133 | if (copy_from_user(bitBuffer, bitBuffer_user, length)) 134 | return EFAULT; 135 | 136 | res = gpio_request(SSI_CLK, "ssi_clk"); 137 | 138 | if (res < 0) { 139 | DBG_LOG("Failed to take control over ssi_clk pin\n"); 140 | 141 | return res; 142 | } 143 | 144 | res = gpio_request(SSI_DATA, "ssi_data"); 145 | 146 | if (res < 0) { 147 | DBG_LOG("Failed to take control over ssi_data pin\n"); 148 | 149 | return res; 150 | } 151 | 152 | i2c_buffer[0] = I2C_IO_EXP_CONFIG_REG; 153 | i2c_buffer[1] = 0xFF; 154 | i2c_buffer[1] &= ~((1 << SSI_PROG) | (1 << MODE1) | (1 << MODE0)); 155 | i2c_master_send(io_cli, i2c_buffer, 2);//set SSI_PROG, MODE0, MODE1 as output others as inputs 156 | i2c_set_pin(io_cli, MODE0, 1); 157 | i2c_set_pin(io_cli, MODE1, 1); 158 | i2c_set_pin(io_cli, SSI_PROG, 0); 159 | 160 | gpio_direction_output(SSI_CLK, 0); 161 | gpio_direction_output(SSI_DATA, 0); 162 | 163 | gpio_set_value(SSI_CLK, 0); 164 | i2c_set_pin(io_cli, SSI_PROG, 1); 165 | __delay_cycles(10 * SSI_DELAY); 166 | i2c_set_pin(io_cli, SSI_PROG, 0); 167 | __delay_cycles(5 * SSI_DELAY); 168 | 169 | while (i2c_get_pin(io_cli, SSI_INIT) > 0 && timer < 200) 170 | timer++;//waiting for init pin to go down 171 | 172 | if (timer >= 200) { 173 | DBG_LOG("FPGA did not answer to prog request, init pin not going low\n"); 174 | i2c_set_pin(io_cli, SSI_PROG, 1); 175 | gpio_free(SSI_CLK); 176 | gpio_free(SSI_DATA); 177 | 178 | return -EIO; 179 | } 180 | 181 | timer = 0; 182 | __delay_cycles(5 * SSI_DELAY); 183 | i2c_set_pin(io_cli, SSI_PROG, 1); 184 | 185 | while (i2c_get_pin(io_cli, SSI_INIT) == 0 && timer < 256) {//need to find a better way ... 186 | timer++;//waiting for init pin to go up 187 | } 188 | 189 | if (timer >= 256) { 190 | DBG_LOG("FPGA did not answer to prog request, init pin not going high\n"); 191 | gpio_free(SSI_CLK); 192 | gpio_free(SSI_DATA); 193 | 194 | return -EIO; 195 | } 196 | 197 | timer = 0; 198 | DBG_LOG("Starting configuration of %d bits\n", length * 8); 199 | 200 | for (i = 0; i < length; i++) { 201 | serialConfigWriteByte(bitBuffer[i]); 202 | schedule(); 203 | } 204 | 205 | DBG_LOG("Waiting for done pin to go high\n"); 206 | 207 | while (timer < 50) { 208 | ssiClearClk(); 209 | __delay_cycles(SSI_DELAY); 210 | ssiSetClk(); 211 | __delay_cycles(SSI_DELAY); 212 | timer++; 213 | } 214 | 215 | gpio_set_value(SSI_CLK, 0); 216 | gpio_set_value(SSI_DATA, 1); 217 | 218 | if (i2c_get_pin(io_cli, SSI_DONE) == 0) { 219 | DBG_LOG("FPGA prog failed, done pin not going high\n"); 220 | gpio_free(SSI_CLK); 221 | gpio_free(SSI_DATA); 222 | 223 | return -EIO; 224 | } 225 | 226 | i2c_buffer[0] = I2C_IO_EXP_CONFIG_REG; 227 | i2c_buffer[1] = 0xDC; 228 | i2c_master_send(io_cli, i2c_buffer, 2);//set all unused config pins as input (keeping mode pins and PROG as output) 229 | gpio_direction_input(SSI_CLK); 230 | gpio_direction_input(SSI_DATA); 231 | gpio_free(SSI_CLK); 232 | gpio_free(SSI_DATA); 233 | iounmap(gpio_regs); 234 | //release_mem_region(GPIO3_BASE + 0x190, 8); 235 | kfree(bitBuffer); 236 | 237 | return length; 238 | } 239 | -------------------------------------------------------------------------------- /beaglebone-black/KERNEL/drivers/misc/cape_logibone/config.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_H__ 2 | #define __CONFIG_H__ 3 | 4 | #include 5 | #include 6 | 7 | // /dev/i2c-1 is only available in Kernel 3.8.13 which is a bug (https://github.com/RobertCNelson/bb-kernel/issues/20) 8 | #if LINUX_VERSION_CODE > KERNEL_VERSION(3,8,13) 9 | #define I2C_ADAPTER 2 10 | #else 11 | #define I2C_ADAPTER 1 12 | #endif 13 | 14 | 15 | int loadBitFile(struct i2c_client * io_cli, const unsigned char * bitBuffer_user, const unsigned int length); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /beaglebone-black/KERNEL/drivers/misc/cape_logibone/drvr.h: -------------------------------------------------------------------------------- 1 | #ifndef __DRVR_H__ 2 | #define __DRVR_H__ 3 | 4 | #include 5 | #include 6 | 7 | #define DBG_LOG(fmt, args...) printk(KERN_INFO DEVICE_NAME ": " fmt, ## args) 8 | 9 | struct drvr_dma { 10 | void * buf; 11 | int dma_chan; 12 | struct dma_chan * chan; 13 | }; 14 | 15 | struct drvr_mem{ 16 | unsigned short * base_addr; 17 | unsigned short * virt_addr; 18 | 19 | //new 20 | struct drvr_dma dma; 21 | 22 | //old 23 | unsigned char * dma_buf; 24 | int dma_chan; 25 | }; 26 | 27 | struct drvr_device{ 28 | struct drvr_mem data ; 29 | struct cdev cdev; 30 | unsigned char opened; 31 | }; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /beaglebone-black/KERNEL/drivers/misc/cape_logibone/generic.h: -------------------------------------------------------------------------------- 1 | #define DEVICE_NAME "logibone" 2 | #define DEVICE_NAME_MEM "logibone_mem" 3 | 4 | //I2C 5 | #define I2C_IO_EXP_ADDR 0x24 6 | 7 | //FPGA 8 | #define FPGA_BASE_ADDR 0x01000000 9 | #define FPGA_MEM_SIZE 131072 10 | 11 | #define MAX_DMA_TRANSFER_IN_BYTES (32768) 12 | -------------------------------------------------------------------------------- /beaglebone-black/KERNEL/drivers/misc/cape_logibone/ioctl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include /* copy_to_user */ 5 | #include "ioctl.h" 6 | #include "drvr.h" 7 | 8 | 9 | long ioctl_init() { 10 | return 0; 11 | } 12 | 13 | void ioctl_exit() { 14 | } 15 | 16 | long dm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){ 17 | printk("ioctl failed \n"); 18 | 19 | return -ENOTTY; 20 | } 21 | -------------------------------------------------------------------------------- /beaglebone-black/KERNEL/drivers/misc/cape_logibone/ioctl.h: -------------------------------------------------------------------------------- 1 | #ifndef __IOCTL_H__ 2 | #define __IOCTL_H__ 3 | 4 | #include 5 | #include 6 | 7 | #define MAJOR_NUM 100 8 | 9 | long ioctl_init(void); 10 | void ioctl_exit(void); 11 | long dm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /beaglebone-black/KERNEL/drivers/misc/cape_logibone/logi_dma.c: -------------------------------------------------------------------------------- 1 | /* 2 | * logi_dma.c - DMA support routines 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "logi_dma.h" 11 | #include "drvr.h" 12 | #include "generic.h" 13 | 14 | //auto detect Linux DMA Engine API (Kernel 4.4+) 15 | #ifndef EDMA_DMA_COMPLETE 16 | #define USE_DMA_ENGINE 17 | #endif 18 | 19 | 20 | static volatile int irqraised1; 21 | static dma_addr_t dmaphysbuf; 22 | static struct completion dma_comp; 23 | #ifdef USE_DMA_ENGINE 24 | static dma_cookie_t cookie; 25 | #endif 26 | 27 | #ifdef USE_DMA_ENGINE 28 | static void dma_callback(void *param) 29 | { 30 | struct drvr_mem *mem_dev = (struct drvr_mem*) param; 31 | struct dma_chan *chan = mem_dev->dma.chan; 32 | 33 | switch (dma_async_is_tx_complete(chan, cookie, NULL, NULL)) { 34 | case DMA_COMPLETE: 35 | irqraised1 = 1; 36 | break; 37 | 38 | case DMA_ERROR: 39 | irqraised1 = -1; 40 | break; 41 | 42 | default: 43 | irqraised1 = -1; 44 | break; 45 | } 46 | 47 | complete(&dma_comp); 48 | } 49 | #else 50 | static void dma_callback(unsigned lch, u16 ch_status, void *data) 51 | { 52 | switch (ch_status) { 53 | case EDMA_DMA_COMPLETE: 54 | irqraised1 = 1; 55 | break; 56 | 57 | case EDMA_DMA_CC_ERROR: 58 | irqraised1 = -1; 59 | break; 60 | 61 | default: 62 | irqraised1 = -1; 63 | break; 64 | } 65 | 66 | complete(&dma_comp); 67 | } 68 | #endif /* USE_DMA_ENGINE */ 69 | 70 | void logi_dma_init(void) 71 | { 72 | init_completion(&dma_comp); 73 | } 74 | 75 | int logi_dma_open(struct drvr_mem* mem_dev, dma_addr_t *physbuf) 76 | { 77 | #ifdef USE_DMA_ENGINE 78 | struct dma_slave_config conf; 79 | dma_cap_mask_t mask; 80 | #endif 81 | 82 | /* Allocate DMA buffer */ 83 | mem_dev->dma.buf = dma_alloc_coherent(NULL, MAX_DMA_TRANSFER_IN_BYTES, 84 | &dmaphysbuf, 0); 85 | 86 | if (!mem_dev->dma.buf) { 87 | DBG_LOG("failed to allocate DMA buffer\n"); 88 | 89 | return -ENOMEM; 90 | } 91 | 92 | *physbuf = dmaphysbuf; 93 | 94 | #ifdef USE_DMA_ENGINE 95 | /* Allocate DMA channel */ 96 | dma_cap_zero(mask); 97 | dma_cap_set(DMA_MEMCPY, mask); 98 | mem_dev->dma.chan = dma_request_channel(mask, NULL, NULL); 99 | 100 | if (!mem_dev->dma.chan) { 101 | return -ENODEV; 102 | } 103 | 104 | /* Configure DMA channel */ 105 | conf.direction = DMA_MEM_TO_MEM; 106 | /*conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;*/ 107 | dmaengine_slave_config(mem_dev->dma.chan, &conf); 108 | 109 | DBG_LOG("Using Linux DMA Engine API"); 110 | #else 111 | mem_dev->dma.dma_chan = edma_alloc_channel(EDMA_CHANNEL_ANY, dma_callback, NULL, EVENTQ_0); 112 | 113 | if (mem_dev->dma.dma_chan < 0) { 114 | DBG_LOG("edma_alloc_channel failed for dma_ch, error: %d\n", mem_dev->dma.dma_chan); 115 | 116 | return mem_dev->dma.dma_chan; 117 | } 118 | 119 | DBG_LOG("Using EDMA/DMA Engine"); 120 | #endif /* USE_DMA_ENGINE */ 121 | 122 | DBG_LOG("EDMA channel %d reserved\n", mem_dev->dma.dma_chan); 123 | 124 | return 0; 125 | } 126 | 127 | void logi_dma_release(struct drvr_mem* mem_dev) 128 | { 129 | #ifdef USE_DMA_ENGINE 130 | dma_release_channel(mem_dev->dma.chan); 131 | #else 132 | edma_free_channel(mem_dev->dma.dma_chan); 133 | #endif /* USE_DMA_ENGINE */ 134 | dma_free_coherent(NULL, MAX_DMA_TRANSFER_IN_BYTES, mem_dev->dma.buf, dmaphysbuf); 135 | } 136 | 137 | int logi_dma_copy(struct drvr_mem* mem_dev, unsigned long trgt_addr, unsigned long src_addr, int count) 138 | { 139 | int result = 0; 140 | 141 | #ifdef USE_DMA_ENGINE 142 | struct dma_chan *chan; 143 | struct dma_device *dev; 144 | struct dma_async_tx_descriptor *tx; 145 | unsigned long flags; 146 | 147 | chan = mem_dev->dma.chan; 148 | dev = chan->device; 149 | flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; 150 | tx = dev->device_prep_dma_memcpy(chan, trgt_addr, src_addr, count, flags); 151 | 152 | if (!tx) { 153 | DBG_LOG("device_prep_dma_memcpy failed\n"); 154 | 155 | return -ENODEV; 156 | } 157 | 158 | irqraised1 = 0u; 159 | dma_comp.done = 0; 160 | /* set the callback and submit the transaction */ 161 | tx->callback = dma_callback; 162 | tx->callback_param = mem_dev; 163 | cookie = dmaengine_submit(tx); 164 | dma_async_issue_pending(chan); 165 | #else 166 | struct edmacc_param param_set; 167 | int dma_ch = mem_dev->dma.dma_chan; 168 | 169 | edma_set_src(dma_ch, src_addr, INCR, W256BIT); 170 | edma_set_dest(dma_ch, trgt_addr, INCR, W256BIT); 171 | edma_set_src_index(dma_ch, 1, 1); 172 | edma_set_dest_index(dma_ch, 1, 1); 173 | /* A Sync Transfer Mode */ 174 | edma_set_transfer_params(dma_ch, count, 1, 1, 1, ASYNC);//one block of one frame of one array of count bytes 175 | 176 | /* Enable the Interrupts on Channel 1 */ 177 | edma_read_slot(dma_ch, ¶m_set); 178 | param_set.opt |= ITCINTEN; 179 | param_set.opt |= TCINTEN; 180 | param_set.opt |= EDMA_TCC(EDMA_CHAN_SLOT(dma_ch)); 181 | edma_write_slot(dma_ch, ¶m_set); 182 | irqraised1 = 0u; 183 | dma_comp.done = 0; 184 | result = edma_start(dma_ch); 185 | 186 | if (result != 0) { 187 | DBG_LOG("edma copy failed\n"); 188 | 189 | return result; 190 | } 191 | 192 | #endif /* USE_DMA_ENGINE */ 193 | 194 | wait_for_completion(&dma_comp); 195 | 196 | /* Check the status of the completed transfer */ 197 | 198 | if (irqraised1 < 0) { 199 | DBG_LOG("edma copy: Event Miss Occured!!!\n"); 200 | #ifdef USE_DMA_ENGINE 201 | dmaengine_terminate_all(chan); 202 | #else 203 | edma_stop(dma_ch); 204 | #endif /* USE_DMA_ENGINE */ 205 | result = -EAGAIN; 206 | } 207 | 208 | return result; 209 | } 210 | 211 | -------------------------------------------------------------------------------- /beaglebone-black/KERNEL/drivers/misc/cape_logibone/logi_dma.h: -------------------------------------------------------------------------------- 1 | #ifndef __LOGI_DMA_H__ 2 | #define __LOGI_DMA_H__ 3 | 4 | #include "drvr.h" 5 | 6 | 7 | void logi_dma_init(void); 8 | int logi_dma_open(struct drvr_mem* mem_dev, dma_addr_t *physbuf); 9 | void logi_dma_release(struct drvr_mem* mem_dev); 10 | int logi_dma_copy(struct drvr_mem* mem_dev, unsigned long trgt_addr, 11 | unsigned long src_addr, int count); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /beaglebone-black/KERNEL/drivers/misc/cape_logibone/main_dma.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | //device tree support 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "generic.h" 17 | #include "drvr.h" 18 | #include "logi_dma.h" 19 | #include "ioctl.h" 20 | 21 | //#define PROFILE //uncoment to enable code profile 22 | 23 | 24 | static int dm_open(struct inode *inode, struct file *filp); 25 | static int dm_release(struct inode *inode, struct file *filp); 26 | static ssize_t dm_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos); 27 | static ssize_t dm_read(struct file *filp, char *buf, size_t count, loff_t *f_pos); 28 | 29 | static struct file_operations dm_ops = { 30 | .read = dm_read, 31 | .write = dm_write, 32 | .compat_ioctl = dm_ioctl, 33 | .unlocked_ioctl = dm_ioctl, 34 | .open = dm_open, 35 | .release = dm_release, 36 | }; 37 | 38 | static dma_addr_t dmaphysbuf = 0; 39 | static unsigned char gDrvrMajor = 0; 40 | static struct device * prog_device; 41 | static struct class * drvr_class; 42 | static struct drvr_device * drvr_devices; 43 | 44 | 45 | #ifdef PROFILE 46 | 47 | static struct timespec start_ts, end_ts;//profile timer 48 | 49 | static inline void start_profile() { 50 | getnstimeofday(&start_ts); 51 | } 52 | 53 | static inline void stop_profile() { 54 | getnstimeofday(&end_ts); 55 | } 56 | 57 | static inline void compute_bandwidth(const unsigned int nb_byte) { 58 | struct timespec dt=timespec_sub(end_ts,start_ts); 59 | long elapsed_u_time=dt.tv_sec*1000000+dt.tv_nsec/1000; 60 | 61 | DBG_LOG("Time=%ld us\n",elapsed_u_time); 62 | DBG_LOG("Bandwidth=%d kBytes/s\n",1000000*(nb_byte>>10)/elapsed_u_time); 63 | } 64 | 65 | #endif 66 | 67 | 68 | static inline ssize_t writeMem(struct file *filp, const char *buf, size_t count, loff_t *f_pos) 69 | { 70 | unsigned short int transfer_size; 71 | ssize_t transferred = 0; 72 | unsigned long src_addr, trgt_addr; 73 | struct drvr_mem * mem_to_write = &(((struct drvr_device *) filp->private_data)->data); 74 | 75 | #ifdef USE_WORD_ADDRESSING 76 | if (count % 2 != 0) { 77 | DBG_LOG("write: Transfer must be 16bits aligned\n"); 78 | 79 | return -EFAULT; 80 | } 81 | #endif 82 | 83 | if (count < MAX_DMA_TRANSFER_IN_BYTES) { 84 | transfer_size = count; 85 | } else { 86 | transfer_size = MAX_DMA_TRANSFER_IN_BYTES; 87 | } 88 | 89 | #ifdef USE_WORD_ADDRESSING 90 | trgt_addr = (unsigned long) &(mem_to_write->base_addr[(*f_pos) / 2]); 91 | #else 92 | trgt_addr = (unsigned long) &(mem_to_write->base_addr[(*f_pos)]); 93 | #endif 94 | 95 | src_addr = (unsigned long) dmaphysbuf; 96 | 97 | if (copy_from_user(mem_to_write->dma.buf, buf, transfer_size)) { 98 | return -EFAULT; 99 | } 100 | 101 | if(transfer_size <= 256){ 102 | memcpy((void *) &(mem_to_write->virt_addr[(*f_pos)]), mem_to_write->dma.buf,transfer_size); 103 | 104 | return transfer_size ; 105 | } 106 | 107 | while (transferred < count) { 108 | int res; 109 | 110 | #ifdef PROFILE 111 | DBG_LOG("Write\n"); 112 | start_profile(); 113 | #endif 114 | 115 | res = logi_dma_copy(mem_to_write, trgt_addr, src_addr, 116 | transfer_size); 117 | if (res < 0) { 118 | DBG_LOG("write: Failed to trigger EDMA transfer\n"); 119 | 120 | return res; 121 | } 122 | 123 | #ifdef PROFILE 124 | stop_profile(); 125 | compute_bandwidth(transfer_size); 126 | #endif 127 | 128 | trgt_addr += transfer_size; 129 | transferred += transfer_size; 130 | 131 | if ((count - transferred) < MAX_DMA_TRANSFER_IN_BYTES) { 132 | transfer_size = count - transferred; 133 | } else { 134 | transfer_size = MAX_DMA_TRANSFER_IN_BYTES; 135 | } 136 | 137 | if (copy_from_user(mem_to_write->dma.buf, &buf[transferred], transfer_size)) { 138 | return -EFAULT; 139 | } 140 | } 141 | 142 | return transferred; 143 | } 144 | 145 | static inline ssize_t readMem(struct file *filp, char *buf, size_t count, loff_t *f_pos) 146 | { 147 | unsigned short int transfer_size; 148 | ssize_t transferred = 0; 149 | unsigned long src_addr, trgt_addr; 150 | 151 | struct drvr_mem * mem_to_read = &(((struct drvr_device *) filp->private_data)->data); 152 | 153 | #ifdef USE_WORD_ADDRESSING 154 | if (count % 2 != 0) { 155 | DBG_LOG("read: Transfer must be 16bits aligned\n"); 156 | 157 | return -EFAULT; 158 | } 159 | #endif 160 | 161 | if (count < MAX_DMA_TRANSFER_IN_BYTES) { 162 | transfer_size = count; 163 | } else { 164 | transfer_size = MAX_DMA_TRANSFER_IN_BYTES; 165 | } 166 | 167 | #ifdef USE_WORD_ADDRESSING 168 | src_addr = (unsigned long) &(mem_to_read->base_addr[(*f_pos) / 2]); 169 | #else 170 | src_addr = (unsigned long) &(mem_to_read->base_addr[(*f_pos)]); 171 | #endif 172 | 173 | trgt_addr = (unsigned long) dmaphysbuf; 174 | 175 | while (transferred < count) { 176 | 177 | #ifdef PROFILE 178 | DBG_LOG("Read\n"); 179 | start_profile(); 180 | #endif 181 | 182 | if(transfer_size <= 256) { 183 | memcpy(mem_to_read->dma.buf, (void *) &(mem_to_read->virt_addr[(*f_pos)+transferred/2]), transfer_size); 184 | } 185 | else { 186 | int res = logi_dma_copy(mem_to_read, trgt_addr, src_addr, transfer_size); 187 | 188 | if (res < 0) { 189 | DBG_LOG("read: Failed to trigger EDMA transfer\n"); 190 | 191 | return res; 192 | } 193 | } 194 | 195 | if (copy_to_user(&buf[transferred], mem_to_read->dma.buf, transfer_size)) { 196 | return -EFAULT; 197 | } 198 | 199 | #ifdef PROFILE 200 | stop_profile(); 201 | compute_bandwidth(transfer_size); 202 | #endif 203 | 204 | src_addr += transfer_size; 205 | transferred += transfer_size; 206 | 207 | if ((count - transferred) < MAX_DMA_TRANSFER_IN_BYTES) { 208 | transfer_size = (count - transferred); 209 | } else { 210 | transfer_size = MAX_DMA_TRANSFER_IN_BYTES; 211 | } 212 | } 213 | 214 | return transferred; 215 | } 216 | 217 | static int dm_open(struct inode *inode, struct file *filp) 218 | { 219 | struct drvr_device* dev = container_of(inode->i_cdev, struct drvr_device, cdev); 220 | 221 | filp->private_data = dev; /* for other methods */ 222 | 223 | if (dev == NULL) { 224 | DBG_LOG("Failed to retrieve driver structure!\n"); 225 | 226 | return -ENODEV; 227 | } 228 | 229 | if (dev->opened != 1) { 230 | struct drvr_mem* mem_dev = &(dev->data); 231 | int result; 232 | 233 | if (request_mem_region((unsigned long) mem_dev->base_addr, FPGA_MEM_SIZE, DEVICE_NAME)==NULL) { 234 | DBG_LOG("Failed to request I/O memory region\n"); 235 | 236 | return -ENOMEM; 237 | } 238 | 239 | mem_dev->virt_addr = ioremap_nocache(((unsigned long) mem_dev->base_addr), FPGA_MEM_SIZE); 240 | 241 | if (mem_dev->virt_addr == NULL) { 242 | DBG_LOG("Failed to remap I/O memory\n"); 243 | 244 | return -ENOMEM; 245 | } 246 | 247 | result = logi_dma_open(mem_dev, &dmaphysbuf); 248 | 249 | if (result != 0) 250 | return result; 251 | 252 | DBG_LOG("mem interface opened \n"); 253 | 254 | dev->opened = 1; 255 | } 256 | 257 | return 0; 258 | } 259 | 260 | static int dm_release(struct inode *inode, struct file *filp) 261 | { 262 | struct drvr_device* dev = container_of(inode->i_cdev, struct drvr_device, cdev); 263 | struct drvr_mem* mem_dev = &(dev->data); 264 | 265 | if (dev->opened != 0) { 266 | iounmap((dev->data).virt_addr); 267 | release_mem_region(((unsigned long) (dev->data).base_addr), FPGA_MEM_SIZE); 268 | logi_dma_release(mem_dev); 269 | DBG_LOG("module released\n"); 270 | } 271 | 272 | dev->opened = 0; 273 | 274 | return 0; 275 | } 276 | 277 | static ssize_t dm_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos) 278 | { 279 | return writeMem(filp, buf, count, f_pos); 280 | } 281 | 282 | static ssize_t dm_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) 283 | { 284 | return readMem(filp, buf, count, f_pos); 285 | } 286 | 287 | static void dm_exit(void) 288 | { 289 | dev_t devno = MKDEV(gDrvrMajor, 0); 290 | 291 | /* Get rid of our char dev entries */ 292 | if (drvr_devices) { 293 | device_destroy(drvr_class, MKDEV(gDrvrMajor, 0)); 294 | cdev_del(&drvr_devices[0].cdev); 295 | kfree(drvr_devices); 296 | } 297 | 298 | class_destroy(drvr_class); 299 | /* cleanup_module is never called if registering failed */ 300 | unregister_chrdev_region(devno, 2); 301 | 302 | ioctl_exit(); 303 | } 304 | 305 | static int dm_init(void) 306 | { 307 | int result; 308 | int devno; 309 | struct drvr_mem * memDev; 310 | 311 | dev_t dev = 0; 312 | result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME); 313 | gDrvrMajor = MAJOR(dev); 314 | 315 | if (result < 0) { 316 | DBG_LOG("Registering char device failed with %d\n", gDrvrMajor); 317 | 318 | return result; 319 | } 320 | 321 | drvr_devices = kmalloc(sizeof(struct drvr_device), GFP_KERNEL); 322 | 323 | if (!drvr_devices) { 324 | dm_exit(); 325 | 326 | return -ENOMEM; 327 | } 328 | 329 | drvr_class = class_create(THIS_MODULE, DEVICE_NAME); 330 | memset(drvr_devices, 0, sizeof(struct drvr_device)); 331 | 332 | //printk(KERN_INFO "'mknod /dev/%s c %d %d'.\n", DEVICE_NAME, gDrvrMajor, 0); 333 | /* Initialize each device. */ 334 | devno = MKDEV(gDrvrMajor, 0); 335 | memDev = &(drvr_devices[0].data); 336 | memDev->base_addr = (unsigned short *) (FPGA_BASE_ADDR); 337 | device_create(drvr_class, prog_device, devno, NULL, DEVICE_NAME_MEM); 338 | cdev_init(&(drvr_devices[0].cdev), &dm_ops); 339 | (drvr_devices[0].cdev).owner = THIS_MODULE; 340 | (drvr_devices[0].cdev).ops = &dm_ops; 341 | cdev_add(&(drvr_devices[0].cdev), devno, 1); 342 | drvr_devices[0].opened = 0; 343 | logi_dma_init(); 344 | 345 | return ioctl_init(); 346 | } 347 | 348 | static const struct of_device_id drvr_of_match[] = { 349 | { .compatible = DEVICE_NAME, }, 350 | { }, 351 | }; 352 | 353 | MODULE_DEVICE_TABLE(of, drvr_of_match); 354 | MODULE_LICENSE("Dual BSD/GPL"); 355 | MODULE_AUTHOR("Jonathan Piat "); 356 | MODULE_AUTHOR("Martin Schmitt "); 357 | 358 | module_init(dm_init); 359 | module_exit(dm_exit); 360 | -------------------------------------------------------------------------------- /beaglebone-black/KERNEL/firmware/capes/BB-BONE-LOGIBONE-00R1.dts: -------------------------------------------------------------------------------- 1 | /* 2 | * Kernel 3.8.13 3 | * optargs=capemgr.disable_partno=BB-BONE-EMMC-2G 4 | * "arch/arm/boot/dts/am335x-boneblack.dts", find the section starting 5 | * with "&mmc2 {" and in section change status = "okay" into "disabled". 6 | * do once : mmc dev 1 7 | * mmc rstn 1 8 | * in uBoot or in uEnv and then delete 9 | */ 10 | 11 | /dts-v1/; 12 | /plugin/; 13 | 14 | / { 15 | compatible = "ti,beaglebone", "ti,beaglebone-black", "ti,beaglebone-green"; 16 | 17 | /* identification */ 18 | part-number = "BB-BONE-LOGIBONE"; 19 | version = "00R1"; 20 | 21 | /* state the resources this cape uses */ 22 | exclusive-use = 23 | /* the pin header uses */ 24 | "P8.25", /* gpmc: gpmc_ad0 */ 25 | "P8.24", /* gpmc: gpmc_ad1 */ 26 | "P8.5", /* gpmc: gpmc_ad2 */ 27 | "P8.6", /* gpmc: gpmc_ad3 */ 28 | "P8.23", /* gpmc: gpmc_ad4 */ 29 | "P8.22", /* gpmc: gpmc_ad5 */ 30 | "P8.3", /* gpmc: gpmc_ad6 */ 31 | "P8.4", /* gpmc: gpmc_ad7 */ 32 | "P8.19", /* gpmc: gpmc_ad8 */ 33 | "P8.13", /* gpmc: gpmc_ad9 */ 34 | "P8.14", /* gpmc: gpmc_ad10 */ 35 | "P8.17", /* gpmc: gpmc_ad11 */ 36 | "P8.12", /* gpmc: gpmc_ad12 */ 37 | "P8.11", /* gpmc: gpmc_ad13 */ 38 | "P8.16", /* gpmc: gpmc_ad14 */ 39 | "P8.15", /* gpmc: gpmc_ad15 */ 40 | "P9.12", /* gpmc: gpmc_ben1 */ 41 | "P8.21", /* gpmc: gpmc_csn1 */ 42 | "P8.18", /* gpmc: gpmc_clk */ 43 | "P8.7", /* gpmc: gpmc_advn_ale */ 44 | "P8.8", /* gpmc: gpmc_oen_ren */ 45 | "P8.10", /* gpmc: gpmc_wen */ 46 | "P8.9", /* gpmc: gpmc_ben0_cle */ 47 | "P9.28", /* BB_SPI_SS */ 48 | "P9.29", /* BB_SPI_MISO */ 49 | "P9.30", /* BB_SPI_MOSI */ 50 | "P9.31", /* BB_SPI_SCK */ 51 | "gpmc"; 52 | /*"eMMC_RSTn";*//* the reset pin */ /* uncomment for use under Kernel 3.8.13 */ 53 | 54 | #address-cells = <1>; 55 | #size-cells = <1>; 56 | 57 | fragment@0 { 58 | target = <&am33xx_pinmux>; 59 | __overlay__ { 60 | 61 | gpmc_pins: pinmux_gpmc_pins { 62 | pinctrl-single,pins = < 63 | 0x000 0x30 /* gpmc_ad0.gpmc_ad0 MODE0 | INPUT | PULLUP */ 64 | 0x004 0x30 /* gpmc_ad1.gpmc_ad1 MODE0 | INPUT | PULLUP */ 65 | 0x008 0x30 /* gpmc_ad2.gpmc_ad2 MODE0 | INPUT | PULLUP */ 66 | 0x00C 0x30 /* gpmc_ad3.gpmc_ad3 MODE0 | INPUT | PULLUP */ 67 | 0x010 0x30 /* gpmc_ad4.gpmc_ad4 MODE0 | INPUT | PULLUP */ 68 | 0x014 0x30 /* gpmc_ad5.gpmc_ad5 MODE0 | INPUT | PULLUP */ 69 | 0x018 0x30 /* gpmc_ad6.gpmc_ad6 MODE0 | INPUT | PULLUP */ 70 | 0x01C 0x30 /* gpmc_ad7.gpmc_ad7 MODE0 | INPUT | PULLUP */ 71 | 0x020 0x30 /* gpmc_ad8.gpmc_ad8 MODE0 | INPUT | PULLUP */ 72 | 0x024 0x30 /* gpmc_ad9.gpmc_ad9 MODE0 | INPUT | PULLUP */ 73 | 0x028 0x30 /* gpmc_ad10.gpmc_ad10 MODE0 | INPUT | PULLUP */ 74 | 0x02C 0x30 /* gpmc_ad11.gpmc_ad11 MODE0 | INPUT | PULLUP */ 75 | 0x030 0x30 /* gpmc_ad12.gpmc_ad12 MODE0 | INPUT | PULLUP */ 76 | 0x034 0x30 /* gpmc_ad13.gpmc_ad13 MODE0 | INPUT | PULLUP */ 77 | 0x038 0x30 /* gpmc_ad14.gpmc_ad14 MODE0 | INPUT | PULLUP */ 78 | 0x03C 0x30 /* gpmc_ad15.gpmc_ad15 MODE0 | INPUT | PULLUP */ 79 | 0x080 0x08 /* gpmc_cscn1.gpmc_cscn1 MODE0 | OUTPUT */ 80 | 0x08C 0x28 /* gpmc_clk.gpmc_clk MODE0 | INPUT */ 81 | 0x090 0x08 /* gpmc_advn_ale.gpmc_advn_ale MODE0 | OUTPUT */ 82 | 0x094 0x08 /* gpmc_oen_ren.gpmc_oen_ren MODE0 | OUTPUT */ 83 | 0x098 0x08 /* gpmc_wen.gpmc_wen MODE0 | OUTPUT */ 84 | 0x09C 0x08 /* gpmc_ben0_cle.gpmc_ben0_cle MODE0 | OUTPUT */ 85 | 0x078 0x08 /* gpmc_ben1_cle.gpmc_ben1_cle MODE0 | OUTPUT */ 86 | >; 87 | }; 88 | 89 | fpga_config_pins: pinmux_fpga_config_pins { 90 | pinctrl-single,pins = < 91 | /* config clk and data */ 92 | 0x190 0x13 /* P9_31 = mcasp0_aclkx.spi1_sclk , OUTPUT_PULLUP | MODE3 */ 93 | 0x194 0x33 /* P9_29 = mcasp0_fsx.spi1_d0 , INPUT_PULLUP | MODE3 */ 94 | 0x198 0x13 /* P9_30 = mcasp0_axr0.spi1_d1 , OUTPUT_PULLUP | MODE3 */ 95 | 0x19c 0x13 /* P9_28 = mcasp0_ahclkr.spi1_cs0 , OUTPUT_PULLUP | MODE3 */ 96 | 97 | >; 98 | }; 99 | }; 100 | }; 101 | 102 | fragment@1 { 103 | target = <&gpmc>; 104 | depth = <1>; /* only create devices on depth 1 */ 105 | 106 | /* stupid warnings */ 107 | #address-cells = <1>; 108 | #size-cells = <1>; 109 | 110 | __overlay__ { 111 | 112 | status = "okay"; 113 | 114 | #address-cells = <2>; 115 | #size-cells = <1>; 116 | 117 | pinctrl-names = "default"; 118 | pinctrl-0 = <&gpmc_pins>; 119 | 120 | /* chip select ranges */ 121 | ranges = <1 0 0x01000000 0x1000000>; 122 | 123 | nor { 124 | compatible = "logibone_ra1"; 125 | status = "okay"; 126 | pinctrl-names = "default"; 127 | pinctrl-0 = <&fpga_config_pins>; 128 | 129 | /*reset = <&rstctl 0 0>;*/ /* uncomment for use under Kernel 3.8.13 */ 130 | /*reset-names = "eMMC_RSTn-LOGIBONE";*/ /* uncomment for use under Kernel 3.8.13 */ 131 | 132 | reg = <1 0 0x01000000>; /*CSn1*/ 133 | 134 | /* CONFIG1 */ 135 | bank-width = <2>; /* GPMC_CONFIG1_DEVICESIZE(1) */ 136 | /*gpmc,burst-write;*/ 137 | /*gpmc,burst-read;*/ 138 | /*gpmc,burst-wrap;*/ 139 | gpmc,sync-read; /* GPMC_CONFIG1_READTYPE_ASYNC */ 140 | gpmc,sync-write; /* GPMC_CONFIG1_WRITETYPE_ASYNC */ 141 | gpmc,clk-activation-ns = <0>; /* GPMC_CONFIG1_CLKACTIVATIONTIME(2) */ 142 | gpmc,burst-length = <16>; /* GPMC_CONFIG1_PAGE_LEN(2) */ 143 | gpmc,mux-add-data = <2>; /* GPMC_CONFIG1_MUXTYPE(2) */ 144 | 145 | /* CONFIG2 */ 146 | gpmc,sync-clk-ps = <20000>; 147 | gpmc,cs-on-ns = <0>; 148 | gpmc,cs-rd-off-ns = <100>; 149 | gpmc,cs-wr-off-ns = <40>; 150 | 151 | /* CONFIG3 */ 152 | gpmc,adv-on-ns = <0>; 153 | gpmc,adv-rd-off-ns = <20>; 154 | gpmc,adv-wr-off-ns = <20>; 155 | 156 | /* CONFIG4 */ 157 | gpmc,we-on-ns = <20>; 158 | gpmc,we-off-ns = <40>; 159 | gpmc,oe-on-ns = <20>; 160 | gpmc,oe-off-ns = <100>; 161 | 162 | /* CONFIG 5 */ 163 | gpmc,page-burst-access-ns = <20>; 164 | gpmc,access-ns = <80>; 165 | gpmc,rd-cycle-ns = <120>; 166 | gpmc,wr-cycle-ns = <60>; 167 | 168 | /* CONFIG 6 */ 169 | gpmc,wr-access-ns = <40>; 170 | gpmc,wr-data-mux-bus-ns = <20>; 171 | /*gpmc,bus-turnaround-ns = <40>;*/ /* CONFIG6:3:0 = 4 */ 172 | /*gpmc,cycle2cycle-samecsen;*/ /* CONFIG6:7 = 1 */ 173 | /*gpmc,cycle2cycle-delay-ns = <40>;*/ /* CONFIG6:11:8 = 4 */ 174 | 175 | /* not using dma engine yet, but we can get the channel number here */ 176 | dmas = <&edma 20>; 177 | dma-names = "logibone"; 178 | 179 | fpga,config { 180 | i2c-adapter = <&i2c2>; 181 | 182 | /* need it to stop the whinning */ 183 | #address-cells = <1>; 184 | #size-cells = <0>; 185 | 186 | /* fake i2c device node */ 187 | pca9534 { 188 | compatible = "logibone"; 189 | reg = <0x24>; 190 | }; 191 | }; 192 | 193 | }; 194 | 195 | }; 196 | }; 197 | 198 | fragment@2 { 199 | target = <&spi1>; 200 | __overlay__ { 201 | 202 | #address-cells = <1>; 203 | #size-cells = <0>; 204 | status = "okay"; 205 | pinctrl-names = "default"; 206 | pinctrl-0 = <&fpga_config_pins>; 207 | ti,pio-mode; 208 | 209 | channel@0 { 210 | #address-cells = <1>; 211 | #size-cells = <0>; 212 | compatible = "spidev"; 213 | reg = <0>; 214 | spi-max-frequency = <16000000>; 215 | spi-cpha; 216 | }; 217 | }; 218 | }; 219 | }; 220 | -------------------------------------------------------------------------------- /beaglebone-black/bbb_quick_setup.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | step 1 4 | 5 | Follow instruction at http://elinux.org/BeagleBoardUbuntu to create your sd card image for the beaglebone-black. (the following uses the latest stable 13.10 saucy) 6 | 7 | step 2 : 8 | 9 | open boot/uEnv.txt and uncomment the line 10 | 11 | #optargs=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN,BB-BONE-EMMC-2G 12 | 13 | if you want to keep HDMI without audio, you can remove the "BB-BONELT-HDMIN" from this line. Using the logibone disable the use of audio (will be fixed in a later sdk revision). 14 | 15 | step 3 : 16 | 17 | boot the beaglebone-black and then connect to 192.168.7.2 (if using usb connection otherwise resolve the IP address) 18 | 19 | ssh ubuntu@192.168.7.2 20 | 21 | 22 | Using an existing module compiled for the default Ubuntu image 23 | 24 | downaload the module and files for your Ubuntu distribution, if you don't find your distribution or the module does not work, contact support@valentfx.com 25 | 26 | 27 | 28 | Installing the compile infrastructure for the kernel module : 29 | 30 | step 1 (On your Linux PC): 31 | 32 | clone the linux-dev repository and move to the beaglebone branch : 33 | 34 | git clone git://github.com/RobertCNelson/linux-dev.git 35 | cd linux-dev 36 | git checkout origin/am33x-v3.8 -b tmp 37 | 38 | verify on http://elinux.org/BeagleBoardUbuntu what kernel version your kernel uses and modify version.sh accordingly : 39 | ex for saucy 13.10 => BeagleBone/BeagleBone Black: v3.8.13-bone40 kernel 40 | 41 | KERNEL_REL=3.8 42 | KERNEL_TAG=${KERNEL_REL}.13 43 | BUILD=bone40 44 | 45 | build the base kernel (may take a few hours depending on your internet connection and PC performances): 46 | 47 | ./build_kernel.sh 48 | 49 | 50 | step 2 (On your Linux PC): 51 | 52 | clone the logi-kernel repository on your computer : 53 | 54 | git clone https://github.com/fpga-logi-dev/logi-kernel.git 55 | 56 | go into the beaglebone-black folder and run build_module.sh with the linux-dev path as argument. 57 | If your board release is different than R1, open the build_module.sh and modify the BOARD_REV variable (ex : BOARD_REV=RA2) before running build_module. 58 | 59 | ./build_module ~/development/KERNEL/ARM/beaglebone-black/linux-dev-13_10/ 60 | 61 | 62 | copy the generated deploy directory onto your beaglebone home directory 63 | 64 | 65 | step 3 (On the beaglebone black): 66 | 67 | connect to the beaglebone black over ssh and install an unpgraded version of dtc, this requires an internet connection for the beaglebone and may take some time: 68 | 69 | wget -c https://raw.github.com/RobertCNelson/tools/master/pkgs/dtc.sh 70 | chmod +x dtc.sh 71 | ./dtc.sh 72 | 73 | 74 | step 4 (On the beaglebone black): go to the copied deploy directory and execute the setup_device_tree_R1.sh script (will load the device tree configuration file and load the kernel module) 75 | 76 | step 6 (On the beaglebone black): Try to load the blink_led demo app using the following command: 77 | 78 | sudo dd id=blink_led.bit of=/dev/logibone bs=4M 79 | 80 | step 7 (On the beaglebone black): 81 | 82 | lcone the logi-tools repository : 83 | git clone https://github.com/fpga-logi-dev/logi-tools.git 84 | 85 | Open the logibone_loader folder and execute install.sh as sudo. 86 | sudo ./install.sh 87 | 88 | try to load the blink_led application using logi_loader 89 | 90 | sudo logi_loader blink_led.bit 91 | 92 | 93 | -------------------------------------------------------------------------------- /beaglebone-black/build_module.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | BOARD_REV=r1 4 | 5 | LINUX_DEV=$1 6 | 7 | 8 | #if problem such as "gcc-linaro-arm-linux-gnueabihf-4.7-2013.04-20130415_linux not found" occurs, locate the actual gcc toolchain 9 | #and modify the path accordingly. Will automate this in a script later 10 | CC_PREFIX=${LINUX_DEV}/dl/gcc-linaro-arm-linux-gnueabihf-4.7-2013.04-20130415_linux/bin/arm-linux-gnueabihf- 11 | KERNEL_DIR=${LINUX_DEV}/KERNEL 12 | 13 | 14 | cd logibone_${BOARD_REV} 15 | make clean 16 | make ARCH=arm CROSS_COMPILE=${CC_PREFIX} KERNELDIR=${KERNEL_DIR} 17 | cd .. 18 | mkdir deploy 19 | cp logibone_${BOARD_REV}/logibone_${BOARD_REV}_dma.ko deploy/ 20 | cp logibone_${BOARD_REV}/setup_device-tree_${BOARD_REV^^}.sh deploy/ 21 | cp logibone_${BOARD_REV}/BB-BONE-LOGIBONE-00${BOARD_REV^^}.dts deploy/ 22 | -------------------------------------------------------------------------------- /beaglebone-black/cape_eeprom/data.eeprom: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fpga-logi/logi-kernel/4e22565f4b42ce955945ed986a642f5e7486b2f4/beaglebone-black/cape_eeprom/data.eeprom -------------------------------------------------------------------------------- /beaglebone-black/cape_eeprom/init_eeprom.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | sudo i2cset -y 1 0x24 0x03 0xBF 4 | sudo i2cset -y 1 0x24 0x01 0x00 5 | cat data.eeprom > /sys/bus/i2c/drivers/at24/1-0054/eeprom 6 | -------------------------------------------------------------------------------- /beaglebone-black/cape_eeprom/mk_logibone_eeprom.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2012 - Cabin Programs, Ken Keller 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | // this software and associated documentation files (the "Software"), to deal in 6 | // the Software without restriction, including without limitation the rights to 7 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 8 | // of the Software, and to permit persons to whom the Software is furnished to do 9 | // so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | // 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #ifndef FALSE 30 | #define FALSE (0) 31 | #define TRUE (!(FALSE)) 32 | #endif 33 | 34 | #define sizeEEPROM 244 35 | unsigned char eeprom[sizeEEPROM+100]; // Give a little extra for no good reason 36 | 37 | 38 | 39 | 40 | #define NB_PIN 27 41 | 42 | 43 | 44 | int logibone_mux_tab [NB_PIN][3] = { 45 | {8, 25,0xE030}, 46 | {8, 24,0xE030}, 47 | {8, 5,0xE030}, 48 | {8, 6,0xE030}, 49 | {8, 23,0xE030}, 50 | {8, 22,0xE030}, 51 | {8, 3,0xE030}, 52 | {8, 4,0xE030}, 53 | {8, 19,0xE030}, 54 | {8, 13,0xE030}, 55 | {8, 14,0xE030}, 56 | {8, 17,0xE030}, 57 | {8, 12,0xE030}, 58 | {8, 11,0xE030}, 59 | {8, 16,0xE030}, 60 | {8, 15,0xE030}, 61 | 62 | {8, 18,0xC028}, 63 | 64 | {8, 21,0xC008}, 65 | {8, 7,0xC008}, 66 | {8, 8,0xC008}, 67 | {8, 10,0xC008}, 68 | {8, 9,0xC008}, 69 | {9, 12,0xC008}, 70 | 71 | {9, 28,0xC013}, 72 | {9, 29,0xC033}, 73 | {9, 30,0xC013}, 74 | {9, 31,0xC013} 75 | }; 76 | 77 | 78 | 79 | 80 | int eepromIndex[2][46] = { 81 | { -1, -1, 140, 142, 132, 134, 170, 176, 172, 174, 146, 144, 118, 120, 82 | 150, 148, 122, 168, 116, 166, 164, 138, 136, 130, 128, 162, 202, 206, 83 | 204, 208, 102, 104, 100, 200, 98, 198, 194, 196, 190, 192, 186, 188, 84 | 182, 184, 178, 180 }, 85 | { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 124, 160, 126, 156, 152, 158, 86 | 94, 92, 106, 108, 90, 88, 154, 112, 220, 110, 216, 214, 210, 212, 218, 87 | -1, 230, -1, 234, 232, 226, 228, 222, 224, 114, 96, -1, -1, -1, -1 } 88 | }; 89 | 90 | int main(int argc, char* argv[]) 91 | { 92 | int number1, number2, numberPin; 93 | char keypressed; 94 | char buffer[100]; 95 | int index, i; 96 | 97 | printf("\n\n---EEPROM MAKER---\n\nThis is a program to make the EEPROM data file for a BeagleBone Cape.\n"); 98 | printf("\nThis program produces an output file named: data.eeprom\n"); 99 | printf("The data file follows EEPROM Format Revision 'A0'\n"); 100 | printf("This data file can be put in the BeagleBone EEPROM by this command on a BeagleBone:\n"); 101 | printf(" > cat data.eeprom >/sys/bus/i2c/drivers/at24/3-005x/eeprom\n"); 102 | printf(" Where: 5x is 54, 55, 56, 57 depending on Cape addressing.\n"); 103 | printf(" NOTE: See blog.azkeller.com for more details.\n"); 104 | printf("\n+++ No warranties or support is implied - sorry for CYA +++\n\n"); 105 | 106 | for(index=0; index32) number2=32; 120 | for(index=0; index4) number2=4; 127 | for(index=0; index16) number2=16; 134 | for(index=0; index16) number2=16; 141 | for(index=0; index16) number2=16; 148 | for(index=0; index 250); 155 | eeprom[236]=number1>>8; 156 | eeprom[237]=number1 & 0xff; 157 | 158 | do { 159 | printf("Enter MAX Current (mA) on VDD_5V Used by Cape (Range 0 to 1000mA): "); 160 | scanf(" %d",&number1);getchar(); 161 | } while (number1 > 1000); 162 | eeprom[238]=number1>>8; 163 | eeprom[239]=number1 & 0xff; 164 | 165 | do { 166 | printf("Enter MAX Current (mA) on SYS_5V Used by Cape (Range 0 to 250mA): "); 167 | scanf(" %d",&number1);getchar(); 168 | } while (number1 > 250); 169 | eeprom[240]=number1>>8; 170 | eeprom[241]=number1 & 0xff; 171 | 172 | do { 173 | printf("Enter Current (mA) Supplied on VDD_5V by Cape (Range 0 to 65535mA): "); 174 | scanf(" %d",&number1);getchar(); 175 | } while (number1 > 65535); 176 | eeprom[242]=number1>>8; 177 | eeprom[243]=number1 & 0xff; 178 | 179 | 180 | eeprom[75]=NB_PIN; 181 | for(i= 0; i < NB_PIN ; i ++){ 182 | unsigned char upper, lower, pin, connector ; 183 | connector = logibone_mux_tab[i][0]; 184 | pin = logibone_mux_tab[i][1] ; 185 | upper = (logibone_mux_tab[i][2] & 0xFF00) >> 8; 186 | lower = (logibone_mux_tab[i][2] & 0x00FF) ; 187 | eeprom[eepromIndex[connector-8][pin-1]] = upper; 188 | eeprom[eepromIndex[connector-8][pin-1]+1] = lower; 189 | } 190 | 191 | /* 192 | do { 193 | printf("\nEnter Number of Pins Used by Cape (Range 0 to 74): "); 194 | scanf(" %d",&numberPin);getchar(); 195 | } while (numberPin > 74); 196 | eeprom[75]=numberPin; 197 | 198 | int connector, pin, usage, type, slew, rx, pull, pullEnabled, mux, validFlag; 199 | 200 | for(index=0; index 9); 210 | 211 | do { 212 | printf("\tPIN # %d - Enter pin number (1 through 46): ",index+1); 213 | scanf(" %d",&pin);getchar(); 214 | } while (pin < 1 || pin > 46); 215 | 216 | if (eepromIndex[connector-8][pin-1] == -1) 217 | { 218 | validFlag = FALSE; 219 | printf("\n*** P%d_%d Can't be used by a Cape... ***\n",connector,pin); 220 | } 221 | } while (!validFlag); 222 | 223 | do { 224 | printf("\tPIN # %d P%d_%d - Usage? 1=pin used, 0=unused: ",index+1,connector,pin); 225 | scanf(" %d",&usage);getchar(); 226 | } while (usage < 0 || usage > 1); 227 | 228 | do { 229 | printf("\tPIN # %d P%d_%d - Type? 1=input, 2=output, 3=bidirectional: ",index+1,connector,pin); 230 | scanf(" %d",&type);getchar(); 231 | } while (type < 1 || type > 3); 232 | 233 | do { 234 | printf("\tPIN # %d P%d_%d - Slew? 0=fast, 1=slow: ",index+1,connector,pin); 235 | scanf(" %d",&slew);getchar(); 236 | } while (slew < 0 || slew > 1); 237 | 238 | do { 239 | printf("\tPIN # %d P%d_%d - RX Enabled? 0=disabled, 1=enabled: ",index+1,connector,pin); 240 | scanf(" %d",&rx);getchar(); 241 | } while (rx < 0 || rx > 1); 242 | 243 | do { 244 | printf("\tPIN # %d P%d_%d - Pullup or Pulldown? 0=pulldown, 1=pullup: ",index+1,connector,pin); 245 | scanf(" %d",&pull);getchar(); 246 | } while (pull < 0 || pull > 1); 247 | 248 | do { 249 | printf("\tPIN # %d P%d_%d - Pull up-down Enabled? 0=enabled, 1=disabled: ",index+1,connector,pin); 250 | scanf(" %d",&pullEnabled);getchar(); 251 | } while (pullEnabled < 0 || pullEnabled > 1); 252 | 253 | do { 254 | printf("\tPIN # %d P%d_%d - Pin Mux Mode? (0 through 7): ",index+1,connector,pin); 255 | scanf(" %d",&mux);getchar(); 256 | } while (mux < 0 || mux > 7); 257 | 258 | unsigned char upper, lower; 259 | 260 | upper = 0; 261 | upper = (usage<<7) | (type<<5); 262 | 263 | lower = 0; 264 | lower = (slew<<6) | (rx<<5) | (pull<<4) | (pullEnabled<<3) | mux; 265 | 266 | eeprom[eepromIndex[connector-8][pin-1]] = upper; 267 | eeprom[eepromIndex[connector-8][pin-1]+1] = lower; 268 | }*/ 269 | 270 | // write data to file 271 | printf("\nCreating output file... ./data.eeprom\n\n"); 272 | char *file = "data.eeprom"; 273 | FILE *p = NULL; 274 | p = fopen(file, "w"); 275 | if (p== NULL) { 276 | printf("Error in opening a file..", file); 277 | return(1); 278 | } 279 | fwrite(eeprom, sizeEEPROM, 1, p); 280 | fclose(p); 281 | 282 | return 0; 283 | } 284 | 285 | -------------------------------------------------------------------------------- /beaglebone-black/common/drvr.h: -------------------------------------------------------------------------------- 1 | #ifndef __DRVR_H__ 2 | #define __DRVR_H__ 3 | 4 | #include 5 | #include 6 | 7 | #define DBG_LOG(fmt, args...) printk(KERN_INFO DEVICE_NAME ": " fmt, ## args) 8 | 9 | enum drvr_type { 10 | prog, 11 | mem 12 | }; 13 | 14 | struct drvr_dma { 15 | void * buf; 16 | int dma_chan; 17 | struct dma_chan * chan; 18 | }; 19 | 20 | struct drvr_prog { 21 | struct i2c_client * i2c_io; 22 | }; 23 | 24 | struct drvr_mem { 25 | unsigned short * base_addr; 26 | unsigned short * virt_addr; 27 | struct drvr_dma dma; 28 | }; 29 | 30 | union drvr_data { 31 | struct drvr_prog prog; 32 | struct drvr_mem mem; 33 | }; 34 | 35 | struct drvr_device { 36 | enum drvr_type type; 37 | union drvr_data data; 38 | struct cdev cdev; 39 | unsigned char opened; 40 | }; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /beaglebone-black/common/logi_dma.c: -------------------------------------------------------------------------------- 1 | /* 2 | * logi_dma.c - DMA support routines 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "logi_dma.h" 11 | #include "drvr.h" 12 | #include "generic.h" 13 | 14 | //auto detect Linux DMA Engine API (Kernel 4.4+) 15 | #ifndef EDMA_DMA_COMPLETE 16 | #define USE_DMA_ENGINE 17 | #endif 18 | 19 | 20 | static volatile int irqraised1; 21 | static dma_addr_t dmaphysbuf; 22 | static struct completion dma_comp; 23 | #ifdef USE_DMA_ENGINE 24 | static dma_cookie_t cookie; 25 | #endif 26 | 27 | #ifdef USE_DMA_ENGINE 28 | static void dma_callback(void *param) 29 | { 30 | struct drvr_mem *mem_dev = (struct drvr_mem*) param; 31 | struct dma_chan *chan = mem_dev->dma.chan; 32 | 33 | switch (dma_async_is_tx_complete(chan, cookie, NULL, NULL)) { 34 | case DMA_COMPLETE: 35 | irqraised1 = 1; 36 | break; 37 | 38 | case DMA_ERROR: 39 | irqraised1 = -1; 40 | break; 41 | 42 | default: 43 | irqraised1 = -1; 44 | break; 45 | } 46 | 47 | complete(&dma_comp); 48 | } 49 | #else 50 | static void dma_callback(unsigned lch, u16 ch_status, void *data) 51 | { 52 | switch (ch_status) { 53 | case EDMA_DMA_COMPLETE: 54 | irqraised1 = 1; 55 | break; 56 | 57 | case EDMA_DMA_CC_ERROR: 58 | irqraised1 = -1; 59 | break; 60 | 61 | default: 62 | irqraised1 = -1; 63 | break; 64 | } 65 | 66 | complete(&dma_comp); 67 | } 68 | #endif /* USE_DMA_ENGINE */ 69 | 70 | void logi_dma_init(void) 71 | { 72 | init_completion(&dma_comp); 73 | } 74 | 75 | int logi_dma_open(struct drvr_mem* mem_dev, dma_addr_t *physbuf) 76 | { 77 | #ifdef USE_DMA_ENGINE 78 | struct dma_slave_config conf; 79 | dma_cap_mask_t mask; 80 | #endif 81 | 82 | /* Allocate DMA buffer */ 83 | mem_dev->dma.buf = dma_alloc_coherent(NULL, MAX_DMA_TRANSFER_IN_BYTES, 84 | &dmaphysbuf, 0); 85 | 86 | if (!mem_dev->dma.buf) { 87 | DBG_LOG("failed to allocate DMA buffer\n"); 88 | 89 | return -ENOMEM; 90 | } 91 | 92 | *physbuf = dmaphysbuf; 93 | 94 | #ifdef USE_DMA_ENGINE 95 | /* Allocate DMA channel */ 96 | dma_cap_zero(mask); 97 | dma_cap_set(DMA_MEMCPY, mask); 98 | mem_dev->dma.chan = dma_request_channel(mask, NULL, NULL); 99 | 100 | if (!mem_dev->dma.chan) { 101 | return -ENODEV; 102 | } 103 | 104 | /* Configure DMA channel */ 105 | conf.direction = DMA_MEM_TO_MEM; 106 | /*conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;*/ 107 | dmaengine_slave_config(mem_dev->dma.chan, &conf); 108 | 109 | DBG_LOG("Using Linux DMA Engine API"); 110 | #else 111 | mem_dev->dma.dma_chan = edma_alloc_channel(EDMA_CHANNEL_ANY, dma_callback, NULL, EVENTQ_0); 112 | 113 | if (mem_dev->dma.dma_chan < 0) { 114 | DBG_LOG("edma_alloc_channel failed for dma_ch, error: %d\n", mem_dev->dma.dma_chan); 115 | 116 | return mem_dev->dma.dma_chan; 117 | } 118 | 119 | DBG_LOG("Using EDMA/DMA Engine"); 120 | #endif /* USE_DMA_ENGINE */ 121 | 122 | DBG_LOG("EDMA channel %d reserved\n", mem_dev->dma.dma_chan); 123 | 124 | return 0; 125 | } 126 | 127 | void logi_dma_release(struct drvr_mem* mem_dev) 128 | { 129 | #ifdef USE_DMA_ENGINE 130 | dma_release_channel(mem_dev->dma.chan); 131 | #else 132 | edma_free_channel(mem_dev->dma.dma_chan); 133 | #endif /* USE_DMA_ENGINE */ 134 | dma_free_coherent(NULL, MAX_DMA_TRANSFER_IN_BYTES, mem_dev->dma.buf, dmaphysbuf); 135 | } 136 | 137 | int logi_dma_copy(struct drvr_mem* mem_dev, unsigned long trgt_addr, unsigned long src_addr, int count) 138 | { 139 | int result = 0; 140 | 141 | #ifdef USE_DMA_ENGINE 142 | struct dma_chan *chan; 143 | struct dma_device *dev; 144 | struct dma_async_tx_descriptor *tx; 145 | unsigned long flags; 146 | 147 | chan = mem_dev->dma.chan; 148 | dev = chan->device; 149 | flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; 150 | tx = dev->device_prep_dma_memcpy(chan, trgt_addr, src_addr, count, flags); 151 | 152 | if (!tx) { 153 | DBG_LOG("device_prep_dma_memcpy failed\n"); 154 | 155 | return -ENODEV; 156 | } 157 | 158 | irqraised1 = 0u; 159 | dma_comp.done = 0; 160 | /* set the callback and submit the transaction */ 161 | tx->callback = dma_callback; 162 | tx->callback_param = mem_dev; 163 | cookie = dmaengine_submit(tx); 164 | dma_async_issue_pending(chan); 165 | #else 166 | struct edmacc_param param_set; 167 | int dma_ch = mem_dev->dma.dma_chan; 168 | 169 | edma_set_src(dma_ch, src_addr, INCR, W256BIT); 170 | edma_set_dest(dma_ch, trgt_addr, INCR, W256BIT); 171 | edma_set_src_index(dma_ch, 1, 1); 172 | edma_set_dest_index(dma_ch, 1, 1); 173 | /* A Sync Transfer Mode */ 174 | edma_set_transfer_params(dma_ch, count, 1, 1, 1, ASYNC);//one block of one frame of one array of count bytes 175 | 176 | /* Enable the Interrupts on Channel 1 */ 177 | edma_read_slot(dma_ch, ¶m_set); 178 | param_set.opt |= ITCINTEN; 179 | param_set.opt |= TCINTEN; 180 | param_set.opt |= EDMA_TCC(EDMA_CHAN_SLOT(dma_ch)); 181 | edma_write_slot(dma_ch, ¶m_set); 182 | irqraised1 = 0u; 183 | dma_comp.done = 0; 184 | result = edma_start(dma_ch); 185 | 186 | if (result != 0) { 187 | DBG_LOG("edma copy failed\n"); 188 | 189 | return result; 190 | } 191 | 192 | #endif /* USE_DMA_ENGINE */ 193 | 194 | wait_for_completion(&dma_comp); 195 | 196 | /* Check the status of the completed transfer */ 197 | 198 | if (irqraised1 < 0) { 199 | DBG_LOG("edma copy: Event Miss Occured!!!\n"); 200 | #ifdef USE_DMA_ENGINE 201 | dmaengine_terminate_all(chan); 202 | #else 203 | edma_stop(dma_ch); 204 | #endif /* USE_DMA_ENGINE */ 205 | result = -EAGAIN; 206 | } 207 | 208 | return result; 209 | } 210 | 211 | -------------------------------------------------------------------------------- /beaglebone-black/common/logi_dma.h: -------------------------------------------------------------------------------- 1 | #ifndef __LOGI_DMA_H__ 2 | #define __LOGI_DMA_H__ 3 | 4 | #include "drvr.h" 5 | 6 | 7 | void logi_dma_init(void); 8 | int logi_dma_open(struct drvr_mem* mem_dev, dma_addr_t *physbuf); 9 | void logi_dma_release(struct drvr_mem* mem_dev); 10 | int logi_dma_copy(struct drvr_mem* mem_dev, unsigned long trgt_addr, 11 | unsigned long src_addr, int count); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /beaglebone-black/common/main_dm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | //device tree support 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "generic.h" 19 | #include "config.h" 20 | #include "drvr.h" 21 | #include "ioctl.h" 22 | 23 | 24 | static int dm_open(struct inode *inode, struct file *filp); 25 | static int dm_release(struct inode *inode, struct file *filp); 26 | static ssize_t dm_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos); 27 | static ssize_t dm_read(struct file *filp, char *buf, size_t count, loff_t *f_pos); 28 | 29 | 30 | static struct i2c_board_info io_exp_info= { 31 | I2C_BOARD_INFO("fpga_ctrl", I2C_IO_EXP_ADDR), 32 | }; 33 | 34 | static struct file_operations dm_ops = { 35 | .read = dm_read, 36 | .write = dm_write, 37 | .compat_ioctl = dm_ioctl, 38 | .unlocked_ioctl = dm_ioctl, 39 | .open = dm_open, 40 | .release = dm_release, 41 | }; 42 | 43 | 44 | static unsigned char gDrvrMajor = 0; 45 | static struct device * prog_device; 46 | static struct class * drvr_class; 47 | static struct drvr_device * drvr_devices; 48 | 49 | 50 | static inline ssize_t writeMem(struct file *filp, const char *buf, size_t count, loff_t *f_pos) 51 | { 52 | unsigned short sBuf; 53 | struct drvr_mem * mem_to_write = &(((struct drvr_device *) filp->private_data)->data.mem); 54 | 55 | if (count == 2) { 56 | if (copy_from_user(&sBuf, buf, count)) 57 | return -EFAULT; 58 | 59 | mem_to_write->virt_addr[(*f_pos) / 2] = sBuf; 60 | 61 | return count; 62 | } 63 | 64 | if (copy_from_user((void *) &(mem_to_write->virt_addr[(*f_pos) / 2]), buf, count)) { 65 | return -EFAULT; 66 | } 67 | 68 | return count; 69 | } 70 | 71 | static inline ssize_t readMem(struct file *filp, char *buf, size_t count, loff_t *f_pos) 72 | { 73 | struct drvr_mem * mem_to_read = &(((struct drvr_device *) filp->private_data)->data.mem); 74 | 75 | if (copy_to_user(buf, (void *) &(mem_to_read->virt_addr[(*f_pos) / 2]), count)) { 76 | return -EFAULT; 77 | } 78 | 79 | return count; 80 | } 81 | 82 | static int dm_open(struct inode *inode, struct file *filp) 83 | { 84 | struct drvr_device* dev = container_of(inode->i_cdev, struct drvr_device, cdev); 85 | 86 | filp->private_data = dev; /* for other methods */ 87 | 88 | if (dev == NULL) { 89 | DBG_LOG("Failed to retrieve driver structure !\n"); 90 | 91 | return -ENODEV; 92 | } 93 | 94 | if (dev->opened != 1) { 95 | if (dev->type != prog) { 96 | struct drvr_mem* mem_dev = &((dev->data).mem); 97 | 98 | if (request_mem_region((unsigned long) mem_dev->base_addr, FPGA_MEM_SIZE, DEVICE_NAME)==NULL) { 99 | DBG_LOG("Failed to request I/O memory region\n"); 100 | 101 | return -ENOMEM; 102 | } 103 | 104 | mem_dev->virt_addr = ioremap_nocache(((unsigned long) mem_dev->base_addr), FPGA_MEM_SIZE); 105 | 106 | if (mem_dev->virt_addr == NULL) { 107 | DBG_LOG("Failed to remap I/O memory\n"); 108 | 109 | return -ENOMEM; 110 | } 111 | 112 | DBG_LOG("mem interface opened\n"); 113 | } 114 | 115 | dev->opened = 1; 116 | } 117 | 118 | return 0; 119 | } 120 | 121 | static int dm_release(struct inode *inode, struct file *filp) 122 | { 123 | struct drvr_device* dev = container_of(inode->i_cdev, struct drvr_device, cdev);; 124 | 125 | if (dev->opened != 0) { 126 | if (dev->type == mem) { 127 | iounmap((dev->data.mem).virt_addr); 128 | release_mem_region(((unsigned long) (dev->data.mem).base_addr), FPGA_MEM_SIZE); 129 | DBG_LOG("module released\n"); 130 | } 131 | 132 | dev->opened = 0; 133 | } 134 | 135 | return 0; 136 | } 137 | 138 | static ssize_t dm_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos) 139 | { 140 | struct drvr_device * dev = filp->private_data; /* for other methods */ 141 | 142 | switch (dev->type) { 143 | case prog: 144 | return loadBitFile((dev->data.prog.i2c_io), buf, count); 145 | 146 | case mem: 147 | return writeMem(filp, buf, count, f_pos); 148 | 149 | default: 150 | return loadBitFile((dev->data.prog.i2c_io), buf, count); 151 | }; 152 | } 153 | 154 | static ssize_t dm_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) 155 | { 156 | struct drvr_device * dev = filp->private_data; /* for other methods */ 157 | 158 | switch (dev->type) { 159 | case prog: 160 | return -EPERM; 161 | 162 | case mem: 163 | return readMem(filp, buf, count, f_pos); 164 | 165 | default: 166 | return -EPERM; 167 | }; 168 | } 169 | 170 | static void dm_exit(void) 171 | { 172 | dev_t devno = MKDEV(gDrvrMajor, 0); 173 | 174 | /* Get rid of our char dev entries */ 175 | if (drvr_devices) { 176 | int i; 177 | 178 | for (i = 1; i >= 0; i--) { 179 | if (i == 0) { 180 | i2c_unregister_device(drvr_devices[i].data.prog.i2c_io); 181 | } 182 | 183 | device_destroy(drvr_class, MKDEV(gDrvrMajor, i)); 184 | cdev_del(&drvr_devices[i].cdev); 185 | } 186 | 187 | kfree(drvr_devices); 188 | } 189 | 190 | class_destroy(drvr_class); 191 | /* cleanup_module is never called if registering failed */ 192 | unregister_chrdev_region(devno, 2); 193 | 194 | ioctl_exit(); 195 | } 196 | 197 | static int dm_init(void) 198 | { 199 | int result; 200 | int devno; 201 | struct drvr_mem * memDev; 202 | struct drvr_prog * progDev; 203 | struct i2c_adapter *i2c_adap; 204 | 205 | dev_t dev = 0; 206 | result = alloc_chrdev_region(&dev, 0, 2, DEVICE_NAME); 207 | gDrvrMajor = MAJOR(dev); 208 | 209 | if (result < 0) { 210 | DBG_LOG("Registering char device failed with %d\n", gDrvrMajor); 211 | 212 | return result; 213 | } 214 | 215 | drvr_devices = kmalloc(2 * sizeof(struct drvr_device), GFP_KERNEL); 216 | 217 | if (!drvr_devices) { 218 | dm_exit(); 219 | 220 | return -ENOMEM; 221 | } 222 | 223 | drvr_class = class_create(THIS_MODULE, DEVICE_NAME); 224 | memset(drvr_devices, 0, 2 * sizeof(struct drvr_device)); 225 | 226 | /*Initializing main mdevice for prog*/ 227 | devno = MKDEV(gDrvrMajor, 0); 228 | drvr_devices[0].type = prog; 229 | progDev = &(drvr_devices[0].data.prog); 230 | prog_device = device_create(drvr_class, NULL, devno, NULL, DEVICE_NAME);//should create /dev entry for main node 231 | drvr_devices[0].opened = 0; 232 | 233 | /*Do the i2c stuff*/ 234 | i2c_adap = i2c_get_adapter(I2C_ADAPTER); 235 | 236 | if (i2c_adap == NULL) { 237 | DBG_LOG("Cannot get I2C adapter %i\n", I2C_ADAPTER); 238 | dm_exit(); 239 | 240 | return -ENODEV; 241 | } 242 | 243 | progDev->i2c_io = i2c_new_device(i2c_adap, &io_exp_info); 244 | 245 | if (prog_device == NULL) { 246 | class_destroy(drvr_class); 247 | drvr_devices[0].opened = 0; 248 | dm_exit(); 249 | 250 | return -ENOMEM; 251 | } 252 | 253 | cdev_init(&(drvr_devices[0].cdev), &dm_ops); 254 | drvr_devices[0].cdev.owner = THIS_MODULE; 255 | drvr_devices[0].cdev.ops = &dm_ops; 256 | cdev_add(&(drvr_devices[0].cdev), devno, 1); 257 | //printk(KERN_INFO "'mknod /dev/%s c %d %d'.\n", DEVICE_NAME, gDrvrMajor, 0); 258 | /* Initialize each device. */ 259 | devno = MKDEV(gDrvrMajor, 1); 260 | drvr_devices[1].type = mem; 261 | memDev = &(drvr_devices[1].data.mem); 262 | memDev->base_addr = (unsigned short *) (FPGA_BASE_ADDR); 263 | device_create(drvr_class, prog_device, devno, NULL, DEVICE_NAME_MEM); 264 | cdev_init(&(drvr_devices[1].cdev), &dm_ops); 265 | (drvr_devices[1].cdev).owner = THIS_MODULE; 266 | (drvr_devices[1].cdev).ops = &dm_ops; 267 | cdev_add(&(drvr_devices[1].cdev), devno, 1); 268 | drvr_devices[1].opened = 0; 269 | 270 | return ioctl_init(); 271 | } 272 | 273 | static const struct of_device_id drvr_of_match[] = { 274 | { .compatible = DEVICE_NAME, }, 275 | { }, 276 | }; 277 | 278 | MODULE_DEVICE_TABLE(of, drvr_of_match); 279 | MODULE_LICENSE("Dual BSD/GPL"); 280 | MODULE_AUTHOR("Jonathan Piat "); 281 | MODULE_AUTHOR("Martin Schmitt "); 282 | 283 | module_init(dm_init); 284 | module_exit(dm_exit); 285 | -------------------------------------------------------------------------------- /beaglebone-black/common/main_dma.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | //device tree support 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "generic.h" 17 | #include "config.h" 18 | #include "drvr.h" 19 | #include "logi_dma.h" 20 | #include "ioctl.h" 21 | 22 | 23 | static int dm_open(struct inode *inode, struct file *filp); 24 | static int dm_release(struct inode *inode, struct file *filp); 25 | static ssize_t dm_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos); 26 | static ssize_t dm_read(struct file *filp, char *buf, size_t count, loff_t *f_pos); 27 | 28 | static struct i2c_board_info io_exp_info= { 29 | I2C_BOARD_INFO("fpga_ctrl", I2C_IO_EXP_ADDR), 30 | }; 31 | 32 | static struct file_operations dm_ops = { 33 | .read = dm_read, 34 | .write = dm_write, 35 | .compat_ioctl = dm_ioctl, 36 | .unlocked_ioctl = dm_ioctl, 37 | .open = dm_open, 38 | .release = dm_release, 39 | }; 40 | 41 | static dma_addr_t dmaphysbuf = 0; 42 | static unsigned char gDrvrMajor = 0; 43 | static struct device * prog_device; 44 | static struct class * drvr_class; 45 | static struct drvr_device * drvr_devices; 46 | 47 | 48 | #ifdef PROFILE 49 | 50 | static struct timespec start_ts, end_ts;//profile timer 51 | 52 | static inline void start_profile() { 53 | getnstimeofday(&start_ts); 54 | } 55 | 56 | static inline void stop_profile() { 57 | getnstimeofday(&end_ts); 58 | } 59 | 60 | static inline void compute_bandwidth(const unsigned int nb_byte) { 61 | struct timespec dt=timespec_sub(end_ts,start_ts); 62 | long elapsed_u_time=dt.tv_sec*1000000+dt.tv_nsec/1000; 63 | 64 | DBG_LOG("Time=%ld us\n",elapsed_u_time); 65 | DBG_LOG("Bandwidth=%d kBytes/s\n",1000000*(nb_byte>>10)/elapsed_u_time); 66 | } 67 | 68 | #endif 69 | 70 | 71 | static inline ssize_t writeMem(struct file *filp, const char *buf, size_t count, loff_t *f_pos) 72 | { 73 | unsigned long src_addr, trgt_addr; 74 | int result; 75 | struct drvr_mem * mem_to_write = &(((struct drvr_device *) filp->private_data)->data.mem); 76 | 77 | #ifdef USE_WORD_ADDRESSING 78 | if (count % 2 != 0) { 79 | DBG_LOG("write: Transfer must be 16bits aligned\n"); 80 | 81 | return -EFAULT; 82 | } 83 | 84 | trgt_addr = (unsigned long) &(mem_to_write->base_addr[(*f_pos) / 2]); 85 | #else 86 | trgt_addr = (unsigned long) &(mem_to_write->base_addr[(*f_pos)]); 87 | #endif 88 | 89 | src_addr = (unsigned long) dmaphysbuf; 90 | 91 | if (count < MAX_DMA_TRANSFER_IN_BYTES) { 92 | #ifdef PROFILE 93 | DBG_LOG("Write\n"); 94 | start_profile(); 95 | #endif 96 | 97 | if (copy_from_user(mem_to_write->dma.buf, buf, count)) { 98 | return -EFAULT; 99 | } 100 | 101 | result = logi_dma_copy(mem_to_write, trgt_addr, src_addr, count); 102 | 103 | if (result < 0) { 104 | DBG_LOG("write: Failed to trigger EDMA transfer\n"); 105 | 106 | return result; 107 | } 108 | 109 | #ifdef PROFILE 110 | stop_profile(); 111 | compute_bandwidth(count); 112 | #endif 113 | 114 | return count; 115 | } else { 116 | ssize_t transferred = 0; 117 | unsigned short int transfer_size; 118 | 119 | transfer_size = MAX_DMA_TRANSFER_IN_BYTES; 120 | 121 | if (copy_from_user(mem_to_write->dma.buf, buf, transfer_size)) { 122 | return -EFAULT; 123 | } 124 | 125 | while (transferred < count) { 126 | #ifdef PROFILE 127 | DBG_LOG("Write\n"); 128 | start_profile(); 129 | #endif 130 | 131 | result = logi_dma_copy(mem_to_write, trgt_addr, src_addr, transfer_size); 132 | 133 | if (result < 0) { 134 | DBG_LOG("write: Failed to trigger EDMA transfer\n"); 135 | 136 | return result; 137 | } 138 | 139 | trgt_addr += transfer_size; 140 | transferred += transfer_size; 141 | 142 | if ((count - transferred) < MAX_DMA_TRANSFER_IN_BYTES) { 143 | transfer_size = count - transferred; 144 | } else { 145 | transfer_size = MAX_DMA_TRANSFER_IN_BYTES; 146 | } 147 | 148 | if (copy_from_user(mem_to_write->dma.buf, &buf[transferred], transfer_size)) { 149 | return -EFAULT; 150 | } 151 | 152 | #ifdef PROFILE 153 | stop_profile(); 154 | compute_bandwidth(transfer_size); 155 | #endif 156 | } 157 | 158 | return transferred; 159 | } 160 | } 161 | 162 | static inline ssize_t readMem(struct file *filp, char *buf, size_t count, loff_t *f_pos) 163 | { 164 | unsigned long src_addr, trgt_addr; 165 | int result; 166 | struct drvr_mem * mem_to_read = &(((struct drvr_device *) filp->private_data)->data.mem); 167 | 168 | #ifdef USE_WORD_ADDRESSING 169 | if (count % 2 != 0) { 170 | DBG_LOG("read: Transfer must be 16bits aligned\n"); 171 | 172 | return -EFAULT; 173 | } 174 | 175 | src_addr = (unsigned long) &(mem_to_read->base_addr[(*f_pos) / 2]); 176 | #else 177 | src_addr = (unsigned long) &(mem_to_read->base_addr[(*f_pos)]); 178 | #endif 179 | 180 | trgt_addr = (unsigned long) dmaphysbuf; 181 | 182 | if (count < MAX_DMA_TRANSFER_IN_BYTES) { 183 | 184 | #ifdef PROFILE 185 | DBG_LOG("Read\n"); 186 | start_profile(); 187 | #endif 188 | 189 | result = logi_dma_copy(mem_to_read, trgt_addr, src_addr, count); 190 | 191 | if (result < 0) { 192 | DBG_LOG("read: Failed to trigger EDMA transfer\n"); 193 | 194 | return result; 195 | } 196 | 197 | if (copy_to_user(buf, mem_to_read->dma.buf, count)) { 198 | return -EFAULT; 199 | } 200 | 201 | #ifdef PROFILE 202 | stop_profile(); 203 | compute_bandwidth(count); 204 | #endif 205 | 206 | return count; 207 | } else { 208 | ssize_t transferred = 0; 209 | unsigned short int transfer_size; 210 | 211 | transfer_size = MAX_DMA_TRANSFER_IN_BYTES; 212 | 213 | while (transferred < count) { 214 | 215 | #ifdef PROFILE 216 | DBG_LOG("Read\n"); 217 | start_profile(); 218 | #endif 219 | 220 | result = logi_dma_copy(mem_to_read, trgt_addr, src_addr, transfer_size); 221 | 222 | if (result < 0) { 223 | DBG_LOG("read: Failed to trigger EDMA transfer\n"); 224 | 225 | return result; 226 | } 227 | 228 | if (copy_to_user(&buf[transferred], mem_to_read->dma.buf, transfer_size)) { 229 | return -EFAULT; 230 | } 231 | 232 | #ifdef PROFILE 233 | stop_profile(); 234 | compute_bandwidth(transfer_size); 235 | #endif 236 | 237 | src_addr += transfer_size; 238 | transferred += transfer_size; 239 | 240 | if ((count - transferred) < MAX_DMA_TRANSFER_IN_BYTES) { 241 | transfer_size = (count - transferred); 242 | } else { 243 | transfer_size = MAX_DMA_TRANSFER_IN_BYTES; 244 | } 245 | } 246 | 247 | return transferred; 248 | } 249 | } 250 | 251 | static int dm_open(struct inode *inode, struct file *filp) 252 | { 253 | struct drvr_device* dev = container_of(inode->i_cdev, struct drvr_device, cdev); 254 | 255 | filp->private_data = dev; /* for other methods */ 256 | 257 | if (dev == NULL) { 258 | DBG_LOG("Failed to retrieve driver structure!\n"); 259 | 260 | return -ENODEV; 261 | } 262 | 263 | if (dev->opened != 1) { 264 | if (dev->type != prog) { 265 | struct drvr_mem* mem_dev = &((dev->data).mem); 266 | int result; 267 | 268 | if (request_mem_region((unsigned long) mem_dev->base_addr, FPGA_MEM_SIZE, DEVICE_NAME)==NULL) { 269 | DBG_LOG("Failed to request I/O memory region\n"); 270 | 271 | return -ENOMEM; 272 | } 273 | 274 | mem_dev->virt_addr = ioremap_nocache(((unsigned long) mem_dev->base_addr), FPGA_MEM_SIZE); 275 | 276 | if (mem_dev->virt_addr == NULL) { 277 | DBG_LOG("Failed to remap I/O memory\n"); 278 | 279 | return -ENOMEM; 280 | } 281 | 282 | result = logi_dma_open(mem_dev, &dmaphysbuf); 283 | 284 | if (result != 0) 285 | return result; 286 | 287 | DBG_LOG("mem interface opened\n"); 288 | } 289 | 290 | dev->opened = 1; 291 | } 292 | 293 | return 0; 294 | } 295 | 296 | static int dm_release(struct inode *inode, struct file *filp) 297 | { 298 | struct drvr_device* dev = container_of(inode->i_cdev, struct drvr_device, cdev); 299 | struct drvr_mem* mem_dev = &((dev->data).mem); 300 | 301 | if (dev->opened != 0) { 302 | if (dev->type == mem) { 303 | iounmap(mem_dev->virt_addr); 304 | release_mem_region(((unsigned long) mem_dev->base_addr), FPGA_MEM_SIZE); 305 | logi_dma_release(mem_dev); 306 | DBG_LOG("module released\n"); 307 | } 308 | 309 | dev->opened = 0; 310 | } 311 | 312 | return 0; 313 | } 314 | 315 | static ssize_t dm_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos) 316 | { 317 | struct drvr_device * dev = filp->private_data; /* for other methods */ 318 | 319 | switch (dev->type) { 320 | case prog: 321 | return loadBitFile((dev->data.prog.i2c_io), buf, count); 322 | 323 | case mem: 324 | return writeMem(filp, buf, count, f_pos); 325 | 326 | default: 327 | return loadBitFile((dev->data.prog.i2c_io), buf, count); 328 | }; 329 | } 330 | 331 | static ssize_t dm_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) 332 | { 333 | struct drvr_device * dev = filp->private_data; /* for other methods */ 334 | 335 | switch (dev->type) { 336 | case prog: 337 | return -EPERM; 338 | 339 | case mem: 340 | return readMem(filp, buf, count, f_pos); 341 | 342 | default: 343 | return -EPERM; 344 | }; 345 | } 346 | 347 | static void dm_exit(void) 348 | { 349 | dev_t devno = MKDEV(gDrvrMajor, 0); 350 | 351 | /* Get rid of our char dev entries */ 352 | if (drvr_devices) { 353 | int i; 354 | 355 | for (i = 1; i >= 0; i--) { 356 | if (i == 0) { 357 | i2c_unregister_device(drvr_devices[i].data.prog.i2c_io); 358 | } 359 | 360 | device_destroy(drvr_class, MKDEV(gDrvrMajor, i)); 361 | cdev_del(&drvr_devices[i].cdev); 362 | } 363 | 364 | kfree(drvr_devices); 365 | } 366 | 367 | class_destroy(drvr_class); 368 | /* cleanup_module is never called if registering failed */ 369 | unregister_chrdev_region(devno, 2); 370 | 371 | ioctl_exit(); 372 | } 373 | 374 | static int dm_init(void) 375 | { 376 | int result; 377 | int devno; 378 | struct drvr_mem * memDev; 379 | struct drvr_prog * progDev; 380 | struct i2c_adapter *i2c_adap; 381 | 382 | dev_t dev = 0; 383 | result = alloc_chrdev_region(&dev, 0, 2, DEVICE_NAME); 384 | gDrvrMajor = MAJOR(dev); 385 | 386 | if (result < 0) { 387 | DBG_LOG("Registering char device failed with %d\n", gDrvrMajor); 388 | 389 | return result; 390 | } 391 | 392 | drvr_devices = kmalloc(2 * sizeof(struct drvr_device), GFP_KERNEL); 393 | 394 | if (!drvr_devices) { 395 | dm_exit(); 396 | 397 | return -ENOMEM; 398 | } 399 | 400 | drvr_class = class_create(THIS_MODULE, DEVICE_NAME); 401 | memset(drvr_devices, 0, 2 * sizeof(struct drvr_device)); 402 | 403 | /*Initializing main mdevice for prog*/ 404 | devno = MKDEV(gDrvrMajor, 0); 405 | drvr_devices[0].type = prog; 406 | progDev = &(drvr_devices[0].data.prog); 407 | prog_device = device_create(drvr_class, NULL, devno, NULL, DEVICE_NAME);//should create /dev entry for main node 408 | drvr_devices[0].opened = 0; 409 | 410 | /*Do the i2c stuff*/ 411 | i2c_adap = i2c_get_adapter(I2C_ADAPTER); 412 | 413 | if (i2c_adap == NULL) { 414 | DBG_LOG("Cannot get I2C adapter %i\n", I2C_ADAPTER); 415 | dm_exit(); 416 | 417 | return -ENODEV; 418 | } 419 | 420 | progDev->i2c_io = i2c_new_device(i2c_adap, &io_exp_info); 421 | 422 | if (prog_device == NULL) { 423 | class_destroy(drvr_class); 424 | drvr_devices[0].opened = 0; 425 | dm_exit(); 426 | 427 | return -ENOMEM; 428 | } 429 | 430 | cdev_init(&(drvr_devices[0].cdev), &dm_ops); 431 | drvr_devices[0].cdev.owner = THIS_MODULE; 432 | drvr_devices[0].cdev.ops = &dm_ops; 433 | cdev_add(&(drvr_devices[0].cdev), devno, 1); 434 | //printk(KERN_INFO "'mknod /dev/%s c %d %d'.\n", DEVICE_NAME, gDrvrMajor, 0); 435 | /* Initialize each device. */ 436 | devno = MKDEV(gDrvrMajor, 1); 437 | drvr_devices[1].type = mem; 438 | memDev = &(drvr_devices[1].data.mem); 439 | memDev->base_addr = (unsigned short *) (FPGA_BASE_ADDR); 440 | device_create(drvr_class, prog_device, devno, NULL, DEVICE_NAME_MEM); 441 | cdev_init(&(drvr_devices[1].cdev), &dm_ops); 442 | (drvr_devices[1].cdev).owner = THIS_MODULE; 443 | (drvr_devices[1].cdev).ops = &dm_ops; 444 | cdev_add(&(drvr_devices[1].cdev), devno, 1); 445 | drvr_devices[1].opened = 0; 446 | logi_dma_init(); 447 | 448 | return ioctl_init(); 449 | } 450 | 451 | static const struct of_device_id drvr_of_match[] = { 452 | { .compatible = DEVICE_NAME, }, 453 | { }, 454 | }; 455 | 456 | MODULE_DEVICE_TABLE(of, drvr_of_match); 457 | MODULE_LICENSE("Dual BSD/GPL"); 458 | MODULE_AUTHOR("Jonathan Piat "); 459 | MODULE_AUTHOR("Martin Schmitt "); 460 | 461 | module_init(dm_init); 462 | module_exit(dm_exit); 463 | -------------------------------------------------------------------------------- /beaglebone-black/logibone_r1/BB-BONE-LOGIBONE-00R1.dts: -------------------------------------------------------------------------------- 1 | /* 2 | * Kernel 3.8.13 3 | * optargs=capemgr.disable_partno=BB-BONE-EMMC-2G 4 | * "arch/arm/boot/dts/am335x-boneblack.dts", find the section starting 5 | * with "&mmc2 {" and in section change status = "okay" into "disabled". 6 | * do once : mmc dev 1 7 | * mmc rstn 1 8 | * in uBoot or in uEnv and then delete 9 | */ 10 | 11 | /dts-v1/; 12 | /plugin/; 13 | 14 | / { 15 | compatible = "ti,beaglebone", "ti,beaglebone-black", "ti,beaglebone-green"; 16 | 17 | /* identification */ 18 | part-number = "BB-BONE-LOGIBONE"; 19 | version = "00R1"; 20 | 21 | /* state the resources this cape uses */ 22 | exclusive-use = 23 | /* the pin header uses */ 24 | "P8.25", /* gpmc: gpmc_ad0 */ 25 | "P8.24", /* gpmc: gpmc_ad1 */ 26 | "P8.5", /* gpmc: gpmc_ad2 */ 27 | "P8.6", /* gpmc: gpmc_ad3 */ 28 | "P8.23", /* gpmc: gpmc_ad4 */ 29 | "P8.22", /* gpmc: gpmc_ad5 */ 30 | "P8.3", /* gpmc: gpmc_ad6 */ 31 | "P8.4", /* gpmc: gpmc_ad7 */ 32 | "P8.19", /* gpmc: gpmc_ad8 */ 33 | "P8.13", /* gpmc: gpmc_ad9 */ 34 | "P8.14", /* gpmc: gpmc_ad10 */ 35 | "P8.17", /* gpmc: gpmc_ad11 */ 36 | "P8.12", /* gpmc: gpmc_ad12 */ 37 | "P8.11", /* gpmc: gpmc_ad13 */ 38 | "P8.16", /* gpmc: gpmc_ad14 */ 39 | "P8.15", /* gpmc: gpmc_ad15 */ 40 | "P9.12", /* gpmc: gpmc_ben1 */ 41 | "P8.21", /* gpmc: gpmc_csn1 */ 42 | "P8.18", /* gpmc: gpmc_clk */ 43 | "P8.7", /* gpmc: gpmc_advn_ale */ 44 | "P8.8", /* gpmc: gpmc_oen_ren */ 45 | "P8.10", /* gpmc: gpmc_wen */ 46 | "P8.9", /* gpmc: gpmc_ben0_cle */ 47 | "P9.28", /* BB_SPI_SS */ 48 | "P9.29", /* BB_SPI_MISO */ 49 | "P9.30", /* BB_SPI_MOSI */ 50 | "P9.31", /* BB_SPI_SCK */ 51 | "gpmc"; 52 | /*"eMMC_RSTn";*//* the reset pin */ /* uncomment for use under Kernel 3.8.13 */ 53 | 54 | #address-cells = <1>; 55 | #size-cells = <1>; 56 | 57 | fragment@0 { 58 | target = <&am33xx_pinmux>; 59 | __overlay__ { 60 | 61 | gpmc_pins: pinmux_gpmc_pins { 62 | pinctrl-single,pins = < 63 | 0x000 0x30 /* gpmc_ad0.gpmc_ad0 MODE0 | INPUT | PULLUP */ 64 | 0x004 0x30 /* gpmc_ad1.gpmc_ad1 MODE0 | INPUT | PULLUP */ 65 | 0x008 0x30 /* gpmc_ad2.gpmc_ad2 MODE0 | INPUT | PULLUP */ 66 | 0x00C 0x30 /* gpmc_ad3.gpmc_ad3 MODE0 | INPUT | PULLUP */ 67 | 0x010 0x30 /* gpmc_ad4.gpmc_ad4 MODE0 | INPUT | PULLUP */ 68 | 0x014 0x30 /* gpmc_ad5.gpmc_ad5 MODE0 | INPUT | PULLUP */ 69 | 0x018 0x30 /* gpmc_ad6.gpmc_ad6 MODE0 | INPUT | PULLUP */ 70 | 0x01C 0x30 /* gpmc_ad7.gpmc_ad7 MODE0 | INPUT | PULLUP */ 71 | 0x020 0x30 /* gpmc_ad8.gpmc_ad8 MODE0 | INPUT | PULLUP */ 72 | 0x024 0x30 /* gpmc_ad9.gpmc_ad9 MODE0 | INPUT | PULLUP */ 73 | 0x028 0x30 /* gpmc_ad10.gpmc_ad10 MODE0 | INPUT | PULLUP */ 74 | 0x02C 0x30 /* gpmc_ad11.gpmc_ad11 MODE0 | INPUT | PULLUP */ 75 | 0x030 0x30 /* gpmc_ad12.gpmc_ad12 MODE0 | INPUT | PULLUP */ 76 | 0x034 0x30 /* gpmc_ad13.gpmc_ad13 MODE0 | INPUT | PULLUP */ 77 | 0x038 0x30 /* gpmc_ad14.gpmc_ad14 MODE0 | INPUT | PULLUP */ 78 | 0x03C 0x30 /* gpmc_ad15.gpmc_ad15 MODE0 | INPUT | PULLUP */ 79 | 0x080 0x08 /* gpmc_cscn1.gpmc_cscn1 MODE0 | OUTPUT */ 80 | 0x08C 0x28 /* gpmc_clk.gpmc_clk MODE0 | INPUT */ 81 | 0x090 0x08 /* gpmc_advn_ale.gpmc_advn_ale MODE0 | OUTPUT */ 82 | 0x094 0x08 /* gpmc_oen_ren.gpmc_oen_ren MODE0 | OUTPUT */ 83 | 0x098 0x08 /* gpmc_wen.gpmc_wen MODE0 | OUTPUT */ 84 | 0x09C 0x08 /* gpmc_ben0_cle.gpmc_ben0_cle MODE0 | OUTPUT */ 85 | 0x078 0x08 /* gpmc_ben1_cle.gpmc_ben1_cle MODE0 | OUTPUT */ 86 | >; 87 | }; 88 | 89 | fpga_config_pins: pinmux_fpga_config_pins { 90 | pinctrl-single,pins = < 91 | /* config clk and data */ 92 | 0x190 0x13 /* P9_31 = mcasp0_aclkx.spi1_sclk , OUTPUT_PULLUP | MODE3 */ 93 | 0x194 0x33 /* P9_29 = mcasp0_fsx.spi1_d0 , INPUT_PULLUP | MODE3 */ 94 | 0x198 0x13 /* P9_30 = mcasp0_axr0.spi1_d1 , OUTPUT_PULLUP | MODE3 */ 95 | 0x19c 0x13 /* P9_28 = mcasp0_ahclkr.spi1_cs0 , OUTPUT_PULLUP | MODE3 */ 96 | 97 | >; 98 | }; 99 | }; 100 | }; 101 | 102 | fragment@1 { 103 | target = <&gpmc>; 104 | depth = <1>; /* only create devices on depth 1 */ 105 | 106 | /* stupid warnings */ 107 | #address-cells = <1>; 108 | #size-cells = <1>; 109 | 110 | __overlay__ { 111 | 112 | status = "okay"; 113 | 114 | #address-cells = <2>; 115 | #size-cells = <1>; 116 | 117 | pinctrl-names = "default"; 118 | pinctrl-0 = <&gpmc_pins>; 119 | 120 | /* chip select ranges */ 121 | ranges = <1 0 0x01000000 0x1000000>; 122 | 123 | nor { 124 | compatible = "logibone_ra1"; 125 | status = "okay"; 126 | pinctrl-names = "default"; 127 | pinctrl-0 = <&fpga_config_pins>; 128 | 129 | /*reset = <&rstctl 0 0>;*/ /* uncomment for use under Kernel 3.8.13 */ 130 | /*reset-names = "eMMC_RSTn-LOGIBONE";*/ /* uncomment for use under Kernel 3.8.13 */ 131 | 132 | reg = <1 0 0x01000000>; /*CSn1*/ 133 | 134 | /* CONFIG1 */ 135 | bank-width = <2>; /* GPMC_CONFIG1_DEVICESIZE(1) */ 136 | /*gpmc,burst-write;*/ 137 | /*gpmc,burst-read;*/ 138 | /*gpmc,burst-wrap;*/ 139 | gpmc,sync-read; /* GPMC_CONFIG1_READTYPE_ASYNC */ 140 | gpmc,sync-write; /* GPMC_CONFIG1_WRITETYPE_ASYNC */ 141 | gpmc,clk-activation-ns = <0>; /* GPMC_CONFIG1_CLKACTIVATIONTIME(2) */ 142 | gpmc,burst-length = <16>; /* GPMC_CONFIG1_PAGE_LEN(2) */ 143 | gpmc,mux-add-data = <2>; /* GPMC_CONFIG1_MUXTYPE(2) */ 144 | 145 | /* CONFIG2 */ 146 | gpmc,sync-clk-ps = <20000>; 147 | gpmc,cs-on-ns = <0>; 148 | gpmc,cs-rd-off-ns = <100>; 149 | gpmc,cs-wr-off-ns = <40>; 150 | 151 | /* CONFIG3 */ 152 | gpmc,adv-on-ns = <0>; 153 | gpmc,adv-rd-off-ns = <20>; 154 | gpmc,adv-wr-off-ns = <20>; 155 | 156 | /* CONFIG4 */ 157 | gpmc,we-on-ns = <20>; 158 | gpmc,we-off-ns = <40>; 159 | gpmc,oe-on-ns = <20>; 160 | gpmc,oe-off-ns = <100>; 161 | 162 | /* CONFIG 5 */ 163 | gpmc,page-burst-access-ns = <20>; 164 | gpmc,access-ns = <80>; 165 | gpmc,rd-cycle-ns = <120>; 166 | gpmc,wr-cycle-ns = <60>; 167 | 168 | /* CONFIG 6 */ 169 | gpmc,wr-access-ns = <40>; 170 | gpmc,wr-data-mux-bus-ns = <20>; 171 | /*gpmc,bus-turnaround-ns = <40>;*/ /* CONFIG6:3:0 = 4 */ 172 | /*gpmc,cycle2cycle-samecsen;*/ /* CONFIG6:7 = 1 */ 173 | /*gpmc,cycle2cycle-delay-ns = <40>;*/ /* CONFIG6:11:8 = 4 */ 174 | 175 | /* not using dma engine yet, but we can get the channel number here */ 176 | dmas = <&edma 20>; 177 | dma-names = "logibone"; 178 | 179 | fpga,config { 180 | i2c-adapter = <&i2c2>; 181 | 182 | /* need it to stop the whinning */ 183 | #address-cells = <1>; 184 | #size-cells = <0>; 185 | 186 | /* fake i2c device node */ 187 | pca9534 { 188 | compatible = "logibone"; 189 | reg = <0x24>; 190 | }; 191 | }; 192 | 193 | }; 194 | 195 | }; 196 | }; 197 | 198 | fragment@2 { 199 | target = <&spi1>; 200 | __overlay__ { 201 | 202 | #address-cells = <1>; 203 | #size-cells = <0>; 204 | status = "okay"; 205 | pinctrl-names = "default"; 206 | pinctrl-0 = <&fpga_config_pins>; 207 | ti,pio-mode; 208 | 209 | channel@0 { 210 | #address-cells = <1>; 211 | #size-cells = <0>; 212 | compatible = "spidev"; 213 | reg = <0>; 214 | spi-max-frequency = <16000000>; 215 | spi-cpha; 216 | }; 217 | }; 218 | }; 219 | }; 220 | -------------------------------------------------------------------------------- /beaglebone-black/logibone_r1/Makefile: -------------------------------------------------------------------------------- 1 | #The following definitions can be added to EXTRA_CFLAGS using -D to change the behaviour of certain modules 2 | #PROFILE: Builds modules including profiling information 3 | #USE_WORD_ADDRESSING: Enables WORD instead of BYTE addressing 4 | EXTRA_CFLAGS=-I$(PWD) -Wall -O2 5 | 6 | # If KERNELRELEASE is defined, we've been invoked from the 7 | # kernel build system and can use its language. 8 | ifneq ($(KERNELRELEASE),) 9 | obj-m := logibone_r1_dma.o 10 | logibone_r1_dma-objs := ../common/main_dma.o ../common/logi_dma.o config.o ioctl.o 11 | 12 | obj-m += logibone_r1_dm.o 13 | logibone_r1_dm-objs := ../common/main_dm.o config.o ioctl.o 14 | # Otherwise we were called directly from the command 15 | # line; invoke the kernel build system. 16 | else 17 | KERNELDIR ?= /lib/modules/$(shell uname -r)/build 18 | PWD := $(shell pwd) 19 | 20 | PHONY += default 21 | default: 22 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 23 | 24 | PHONY += clean 25 | clean: 26 | rm -f *.o *.ko .*.cmd *.mod.c *.order *.symvers ../common/*.o ../common/.*.cmd 27 | rm -rf .tmp_versions 28 | endif 29 | -------------------------------------------------------------------------------- /beaglebone-black/logibone_r1/config.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "generic.h" 7 | #include "../common/drvr.h" 8 | 9 | 10 | //SSI 11 | #define SSI_CLK 110 12 | #define SSI_DATA 112 13 | #define SSI_DONE 3 14 | #define SSI_PROG 5 15 | #define SSI_INIT 2 16 | #define MODE0 0 17 | #define MODE1 1 18 | #define SSI_DELAY 1 19 | 20 | //GPIO 21 | #define GPIO3_BASE 0x481AE000 22 | #define GPIO3_SETDATAOUT *(gpio_regs+1) 23 | #define GPIO3_CLEARDATAOUT *(gpio_regs) 24 | 25 | //I2C 26 | #define I2C_IO_EXP_CONFIG_REG 0x03 27 | #define I2C_IO_EXP_IN_REG 0x00 28 | #define I2C_IO_EXP_OUT_REG 0x01 29 | 30 | 31 | volatile unsigned * gpio_regs; 32 | 33 | 34 | static inline void __delay_cycles(unsigned long cycles) 35 | { 36 | while (cycles != 0) { 37 | cycles--; 38 | } 39 | } 40 | 41 | static inline void ssiSetClk(void) 42 | { 43 | //gpio_set_value(SSI_CLK, 1); 44 | GPIO3_SETDATAOUT = (1 << 14); 45 | } 46 | 47 | static inline void ssiClearClk(void) 48 | { 49 | //gpio_set_value(SSI_CLK, 0); 50 | GPIO3_CLEARDATAOUT = (1 << 14); 51 | } 52 | 53 | static inline void ssiSetData(void) 54 | { 55 | //gpio_set_value(SSI_DATA, 1); 56 | GPIO3_SETDATAOUT = (1 << 16); 57 | } 58 | 59 | static inline void ssiClearData(void) 60 | { 61 | //gpio_set_value(SSI_DATA, 0); 62 | GPIO3_CLEARDATAOUT = (1 << 16); 63 | } 64 | 65 | static inline void serialConfigWriteByte(unsigned char val) 66 | { 67 | unsigned char bitCount = 0; 68 | unsigned char valBuf = val; 69 | 70 | for (bitCount = 0; bitCount < 8; bitCount++) { 71 | ssiClearClk(); 72 | 73 | if ((valBuf & 0x80) != 0) { 74 | ssiSetData(); 75 | } else { 76 | ssiClearData(); 77 | } 78 | 79 | //__delay_cycles(SSI_DELAY); 80 | ssiSetClk(); 81 | valBuf = (valBuf << 1); 82 | //__delay_cycles(SSI_DELAY); 83 | } 84 | } 85 | 86 | static inline void i2c_set_pin(struct i2c_client * io_cli, unsigned char pin, unsigned char val) 87 | { 88 | unsigned char i2c_buffer[2]; 89 | 90 | i2c_buffer[0] = I2C_IO_EXP_OUT_REG; 91 | i2c_master_send(io_cli, i2c_buffer, 1); 92 | i2c_master_recv(io_cli, &i2c_buffer[1], 1); 93 | 94 | if (val == 1) { 95 | i2c_buffer[1] |= (1 << pin); 96 | } else { 97 | i2c_buffer[1] &= ~(1 << pin); 98 | } 99 | 100 | i2c_master_send(io_cli, i2c_buffer, 2); 101 | } 102 | 103 | static inline unsigned char i2c_get_pin(struct i2c_client * io_cli, unsigned char pin) 104 | { 105 | unsigned char i2c_buffer; 106 | 107 | i2c_buffer = I2C_IO_EXP_IN_REG; 108 | i2c_master_send(io_cli, &i2c_buffer, 1); 109 | i2c_master_recv(io_cli, &i2c_buffer, 1); 110 | 111 | return ((i2c_buffer >> pin) & 0x01); 112 | } 113 | 114 | int loadBitFile(struct i2c_client * io_cli, const unsigned char * bitBuffer_user, const unsigned int length) 115 | { 116 | int res; 117 | unsigned long int i; 118 | unsigned long int timer = 0; 119 | unsigned char * bitBuffer; 120 | unsigned char i2c_buffer[4]; 121 | 122 | //request_mem_region(GPIO3_BASE + 0x190, 8, gDrvrName); 123 | gpio_regs = ioremap_nocache(GPIO3_BASE + 0x190, 2 * sizeof(int)); 124 | 125 | bitBuffer = kmalloc(length, GFP_KERNEL); 126 | 127 | if (bitBuffer == NULL) { 128 | DBG_LOG("Failed allocate buffer for configuration file\n"); 129 | 130 | return -ENOMEM; 131 | } 132 | 133 | if (copy_from_user(bitBuffer, bitBuffer_user, length)) 134 | return EFAULT; 135 | 136 | res = gpio_request(SSI_CLK, "ssi_clk"); 137 | 138 | if (res < 0) { 139 | DBG_LOG("Failed to take control over ssi_clk pin\n"); 140 | 141 | return res; 142 | } 143 | 144 | res = gpio_request(SSI_DATA, "ssi_data"); 145 | 146 | if (res < 0) { 147 | DBG_LOG("Failed to take control over ssi_data pin\n"); 148 | 149 | return res; 150 | } 151 | 152 | i2c_buffer[0] = I2C_IO_EXP_CONFIG_REG; 153 | i2c_buffer[1] = 0xFF; 154 | i2c_buffer[1] &= ~((1 << SSI_PROG) | (1 << MODE1) | (1 << MODE0)); 155 | i2c_master_send(io_cli, i2c_buffer, 2);//set SSI_PROG, MODE0, MODE1 as output others as inputs 156 | i2c_set_pin(io_cli, MODE0, 1); 157 | i2c_set_pin(io_cli, MODE1, 1); 158 | i2c_set_pin(io_cli, SSI_PROG, 0); 159 | 160 | gpio_direction_output(SSI_CLK, 0); 161 | gpio_direction_output(SSI_DATA, 0); 162 | 163 | gpio_set_value(SSI_CLK, 0); 164 | i2c_set_pin(io_cli, SSI_PROG, 1); 165 | __delay_cycles(10 * SSI_DELAY); 166 | i2c_set_pin(io_cli, SSI_PROG, 0); 167 | __delay_cycles(5 * SSI_DELAY); 168 | 169 | while (i2c_get_pin(io_cli, SSI_INIT) > 0 && timer < 200) 170 | timer++;//waiting for init pin to go down 171 | 172 | if (timer >= 200) { 173 | DBG_LOG("FPGA did not answer to prog request, init pin not going low\n"); 174 | i2c_set_pin(io_cli, SSI_PROG, 1); 175 | gpio_free(SSI_CLK); 176 | gpio_free(SSI_DATA); 177 | 178 | return -EIO; 179 | } 180 | 181 | timer = 0; 182 | __delay_cycles(5 * SSI_DELAY); 183 | i2c_set_pin(io_cli, SSI_PROG, 1); 184 | 185 | while (i2c_get_pin(io_cli, SSI_INIT) == 0 && timer < 256) {//need to find a better way ... 186 | timer++;//waiting for init pin to go up 187 | } 188 | 189 | if (timer >= 256) { 190 | DBG_LOG("FPGA did not answer to prog request, init pin not going high\n"); 191 | gpio_free(SSI_CLK); 192 | gpio_free(SSI_DATA); 193 | 194 | return -EIO; 195 | } 196 | 197 | timer = 0; 198 | DBG_LOG("Starting configuration of %d bits\n", length * 8); 199 | 200 | for (i = 0; i < length; i++) { 201 | serialConfigWriteByte(bitBuffer[i]); 202 | schedule(); 203 | } 204 | 205 | DBG_LOG("Waiting for done pin to go high\n"); 206 | 207 | while (timer < 50) { 208 | ssiClearClk(); 209 | __delay_cycles(SSI_DELAY); 210 | ssiSetClk(); 211 | __delay_cycles(SSI_DELAY); 212 | timer++; 213 | } 214 | 215 | gpio_set_value(SSI_CLK, 0); 216 | gpio_set_value(SSI_DATA, 1); 217 | 218 | if (i2c_get_pin(io_cli, SSI_DONE) == 0) { 219 | DBG_LOG("FPGA prog failed, done pin not going high\n"); 220 | gpio_free(SSI_CLK); 221 | gpio_free(SSI_DATA); 222 | 223 | return -EIO; 224 | } 225 | 226 | i2c_buffer[0] = I2C_IO_EXP_CONFIG_REG; 227 | i2c_buffer[1] = 0xDC; 228 | i2c_master_send(io_cli, i2c_buffer, 2);//set all unused config pins as input (keeping mode pins and PROG as output) 229 | gpio_direction_input(SSI_CLK); 230 | gpio_direction_input(SSI_DATA); 231 | gpio_free(SSI_CLK); 232 | gpio_free(SSI_DATA); 233 | iounmap(gpio_regs); 234 | //release_mem_region(GPIO3_BASE + 0x190, 8); 235 | kfree(bitBuffer); 236 | 237 | return length; 238 | } 239 | -------------------------------------------------------------------------------- /beaglebone-black/logibone_r1/config.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_H__ 2 | #define __CONFIG_H__ 3 | 4 | #include 5 | #include 6 | 7 | // /dev/i2c-1 is only available in Kernel 3.8.13 which is a bug (https://github.com/RobertCNelson/bb-kernel/issues/20) 8 | #if LINUX_VERSION_CODE > KERNEL_VERSION(3,8,13) 9 | #define I2C_ADAPTER 2 10 | #else 11 | #define I2C_ADAPTER 1 12 | #endif 13 | 14 | 15 | int loadBitFile(struct i2c_client * io_cli, const unsigned char * bitBuffer_user, const unsigned int length); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /beaglebone-black/logibone_r1/generic.h: -------------------------------------------------------------------------------- 1 | #define DEVICE_NAME "logibone" 2 | #define DEVICE_NAME_MEM "logibone_mem" 3 | 4 | //I2C 5 | #define I2C_IO_EXP_ADDR 0x24 6 | 7 | //FPGA 8 | #define FPGA_BASE_ADDR 0x01000000 9 | #define FPGA_MEM_SIZE 131072 10 | 11 | #define MAX_DMA_TRANSFER_IN_BYTES (32768) 12 | -------------------------------------------------------------------------------- /beaglebone-black/logibone_r1/ioctl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include /* copy_to_user */ 5 | #include "ioctl.h" 6 | #include "../common/drvr.h" 7 | 8 | 9 | long ioctl_init() { 10 | return 0; 11 | } 12 | 13 | void ioctl_exit() { 14 | } 15 | 16 | long dm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){ 17 | printk("ioctl failed \n"); 18 | 19 | return -ENOTTY; 20 | } 21 | -------------------------------------------------------------------------------- /beaglebone-black/logibone_r1/ioctl.h: -------------------------------------------------------------------------------- 1 | #ifndef __IOCTL_H__ 2 | #define __IOCTL_H__ 3 | 4 | #include 5 | #include 6 | 7 | #define MAJOR_NUM 100 8 | 9 | long ioctl_init(void); 10 | void ioctl_exit(void); 11 | long dm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); 12 | 13 | #endif 14 | 15 | 16 | -------------------------------------------------------------------------------- /beaglebone-black/logibone_r1/setup_device-tree_R1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | CAPE_MNGR="$(ls /sys/devices/ | grep bone_capemgr)" 4 | 5 | if [ -z "$CAPE_MNGR" ]; then 6 | SLOTS=/sys/devices/platform/bone_capemgr/slots 7 | else 8 | SLOTS=/sys/devices/$CAPE_MNGR/slots 9 | fi 10 | 11 | rm /lib/firmware/BB-BONE-LOGIBONE-00R1.dtbo 12 | dtc -O dtb -o BB-BONE-LOGIBONE-00R1.dtbo -b 0 -@ BB-BONE-LOGIBONE-00R1.dts 13 | cp BB-BONE-LOGIBONE-00R1.dtbo /lib/firmware 14 | 15 | #sh -c "echo -4 > ${SLOTS}" 16 | #sh -c "echo -5 > ${SLOTS}" 17 | #sh -c "echo -6 > ${SLOTS}" 18 | sh -c "echo BB-BONE-LOGIBONE:00A3 > ${SLOTS}" 19 | 20 | cat ${SLOTS} 21 | 22 | insmod logibone_r1_dma.ko 23 | -------------------------------------------------------------------------------- /beaglebone-black/logibone_ra2/BB-BONE-LOGIBONE-00A3.dts: -------------------------------------------------------------------------------- 1 | /* 2 | * Kernel 3.8.13 3 | * optargs=capemgr.disable_partno=BB-BONE-EMMC-2G 4 | * "arch/arm/boot/dts/am335x-boneblack.dts", find the section starting 5 | * with "&mmc2 {" and in section change status = "okay" into "disabled". 6 | * do once : mmc dev 1 7 | * mmc rstn 1 8 | * in uBoot or in uEnv and then delete 9 | */ 10 | 11 | /dts-v1/; 12 | /plugin/; 13 | 14 | / { 15 | compatible = "ti,beaglebone", "ti,beaglebone-black", "ti,beaglebone-green"; 16 | 17 | /* identification */ 18 | part-number = "BB-BONE-LOGIBONE"; 19 | version = "00A3"; 20 | 21 | /* state the resources this cape uses */ 22 | exclusive-use = 23 | /* the pin header uses */ 24 | "P8.25", /* gpmc: gpmc_ad0 */ 25 | "P8.24", /* gpmc: gpmc_ad1 */ 26 | "P8.5", /* gpmc: gpmc_ad2 */ 27 | "P8.6", /* gpmc: gpmc_ad3 */ 28 | "P8.23", /* gpmc: gpmc_ad4 */ 29 | "P8.22", /* gpmc: gpmc_ad5 */ 30 | "P8.3", /* gpmc: gpmc_ad6 */ 31 | "P8.4", /* gpmc: gpmc_ad7 */ 32 | "P8.19", /* gpmc: gpmc_ad8 */ 33 | "P8.13", /* gpmc: gpmc_ad9 */ 34 | "P8.14", /* gpmc: gpmc_ad10 */ 35 | "P8.17", /* gpmc: gpmc_ad11 */ 36 | "P8.12", /* gpmc: gpmc_ad12 */ 37 | "P8.11", /* gpmc: gpmc_ad13 */ 38 | "P8.16", /* gpmc: gpmc_ad14 */ 39 | "P8.15", /* gpmc: gpmc_ad15 */ 40 | "P9.12", /* gpmc: gpmc_ben1 */ 41 | "P8.21", /* gpmc: gpmc_csn1 */ 42 | "P8.18", /* gpmc: gpmc_clk */ 43 | "P8.7", /* gpmc: gpmc_advn_ale */ 44 | "P8.8", /* gpmc: gpmc_oen_ren */ 45 | "P8.10", /* gpmc: gpmc_wen */ 46 | "P8.9", /* gpmc: gpmc_ben0_cle */ 47 | "P9.28", /* BB_SPI_SS */ 48 | "P9.29", /* BB_SPI_MISO */ 49 | "P9.30", /* BB_SPI_MOSI */ 50 | "P9.31", /* BB_SPI_SCK */ 51 | "gpmc"; 52 | /*"eMMC_RSTn";*//* the reset pin */ /* uncomment for use under Kernel 3.8.13 */ 53 | 54 | #address-cells = <1>; 55 | #size-cells = <1>; 56 | 57 | fragment@0 { 58 | target = <&am33xx_pinmux>; 59 | __overlay__ { 60 | 61 | gpmc_pins: pinmux_gpmc_pins { 62 | pinctrl-single,pins = < 63 | 0x000 0x30 /* gpmc_ad0.gpmc_ad0 MODE0 | INPUT | PULLUP */ 64 | 0x004 0x30 /* gpmc_ad1.gpmc_ad1 MODE0 | INPUT | PULLUP */ 65 | 0x008 0x30 /* gpmc_ad2.gpmc_ad2 MODE0 | INPUT | PULLUP */ 66 | 0x00C 0x30 /* gpmc_ad3.gpmc_ad3 MODE0 | INPUT | PULLUP */ 67 | 0x010 0x30 /* gpmc_ad4.gpmc_ad4 MODE0 | INPUT | PULLUP */ 68 | 0x014 0x30 /* gpmc_ad5.gpmc_ad5 MODE0 | INPUT | PULLUP */ 69 | 0x018 0x30 /* gpmc_ad6.gpmc_ad6 MODE0 | INPUT | PULLUP */ 70 | 0x01C 0x30 /* gpmc_ad7.gpmc_ad7 MODE0 | INPUT | PULLUP */ 71 | 0x020 0x30 /* gpmc_ad8.gpmc_ad8 MODE0 | INPUT | PULLUP */ 72 | 0x024 0x30 /* gpmc_ad9.gpmc_ad9 MODE0 | INPUT | PULLUP */ 73 | 0x028 0x30 /* gpmc_ad10.gpmc_ad10 MODE0 | INPUT | PULLUP */ 74 | 0x02C 0x30 /* gpmc_ad11.gpmc_ad11 MODE0 | INPUT | PULLUP */ 75 | 0x030 0x30 /* gpmc_ad12.gpmc_ad12 MODE0 | INPUT | PULLUP */ 76 | 0x034 0x30 /* gpmc_ad13.gpmc_ad13 MODE0 | INPUT | PULLUP */ 77 | 0x038 0x30 /* gpmc_ad14.gpmc_ad14 MODE0 | INPUT | PULLUP */ 78 | 0x03C 0x30 /* gpmc_ad15.gpmc_ad15 MODE0 | INPUT | PULLUP */ 79 | 0x080 0x08 /* gpmc_cscn1.gpmc_cscn1 MODE0 | OUTPUT */ 80 | 0x08C 0x28 /* gpmc_clk.gpmc_clk MODE0 | INPUT */ 81 | 0x090 0x08 /* gpmc_advn_ale.gpmc_advn_ale MODE0 | OUTPUT */ 82 | 0x094 0x08 /* gpmc_oen_ren.gpmc_oen_ren MODE0 | OUTPUT */ 83 | 0x098 0x08 /* gpmc_wen.gpmc_wen MODE0 | OUTPUT */ 84 | 0x09C 0x08 /* gpmc_ben0_cle.gpmc_ben0_cle MODE0 | OUTPUT */ 85 | 0x078 0x08 /* gpmc_ben1_cle.gpmc_ben1_cle MODE0 | OUTPUT */ 86 | >; 87 | }; 88 | 89 | fpga_config_pins: pinmux_fpga_config_pins { 90 | pinctrl-single,pins = < 91 | /* config clk and data */ 92 | 0x198 0x37 /* spi1_d1 MODE3 | INPUT | PULLUP , serial data config */ 93 | 0x190 0x37 /* spi1_sclk MODE3 | INPUT | PULLUP, serial clock config */ 94 | >; 95 | }; 96 | }; 97 | }; 98 | 99 | fragment@1 { 100 | target = <&gpmc>; 101 | depth = <1>; /* only create devices on depth 1 */ 102 | 103 | /* stupid warnings */ 104 | #address-cells = <1>; 105 | #size-cells = <1>; 106 | 107 | __overlay__ { 108 | 109 | status = "okay"; 110 | 111 | #address-cells = <2>; 112 | #size-cells = <1>; 113 | 114 | pinctrl-names = "default"; 115 | pinctrl-0 = <&gpmc_pins>; 116 | 117 | /* chip select ranges */ 118 | ranges = <1 0 0x01000000 0x1000000>; 119 | 120 | nor { 121 | compatible = "logibone"; 122 | status = "okay"; 123 | pinctrl-names = "default"; 124 | pinctrl-0 = <&fpga_config_pins>; 125 | 126 | /*reset = <&rstctl 0 0>;*/ /* uncomment for use under Kernel 3.8.13 */ 127 | /*reset-names = "eMMC_RSTn-LOGIBONE";*/ /* uncomment for use under Kernel 3.8.13 */ 128 | 129 | reg = <1 0 0x01000000>; /*CSn1*/ 130 | 131 | /* CONFIG1 */ 132 | bank-width = <2>; /* GPMC_CONFIG1_DEVICESIZE(1) */ 133 | /*gpmc,burst-write;*/ 134 | gpmc,burst-read; 135 | gpmc,burst-wrap; 136 | gpmc,sync-read; /* GPMC_CONFIG1_READTYPE_ASYNC */ 137 | gpmc,sync-write; /* GPMC_CONFIG1_WRITETYPE_ASYNC */ 138 | gpmc,clk-activation-ns = <0>; /* GPMC_CONFIG1_CLKACTIVATIONTIME(2) */ 139 | gpmc,burst-length = <16>; /* GPMC_CONFIG1_PAGE_LEN(2) */ 140 | gpmc,mux-add-data = <2>; /* GPMC_CONFIG1_MUXTYPE(2) */ 141 | 142 | /* CONFIG2 */ 143 | gpmc,sync-clk-ps = <20000>; 144 | gpmc,cs-on-ns = <0>; 145 | gpmc,cs-rd-off-ns = <100>; 146 | gpmc,cs-wr-off-ns = <40>; 147 | 148 | /* CONFIG3 */ 149 | gpmc,adv-on-ns = <0>; 150 | gpmc,adv-rd-off-ns = <20>; 151 | gpmc,adv-wr-off-ns = <20>; 152 | 153 | /* CONFIG4 */ 154 | gpmc,we-on-ns = <20>; 155 | gpmc,we-off-ns = <40>; 156 | gpmc,oe-on-ns = <20>; 157 | gpmc,oe-off-ns = <100>; 158 | 159 | /* CONFIG 5 */ 160 | gpmc,page-burst-access-ns = <20>; 161 | gpmc,access-ns = <80>; 162 | gpmc,rd-cycle-ns = <120>; 163 | gpmc,wr-cycle-ns = <60>; 164 | 165 | /* CONFIG 6 */ 166 | gpmc,wr-access-ns = <40>; 167 | gpmc,wr-data-mux-bus-ns = <20>; 168 | /*gpmc,bus-turnaround-ns = <40>;*/ /* CONFIG6:3:0 = 4 */ 169 | /*gpmc,cycle2cycle-samecsen;*/ /* CONFIG6:7 = 1 */ 170 | /*gpmc,cycle2cycle-delay-ns = <40>;*/ /* CONFIG6:11:8 = 4 */ 171 | 172 | /* not using dma engine yet, but we can get the channel number here */ 173 | dmas = <&edma 20>; 174 | dma-names = "logibone"; 175 | 176 | fpga,config { 177 | i2c-adapter = <&i2c2>; 178 | 179 | /* need it to stop the whinning */ 180 | #address-cells = <1>; 181 | #size-cells = <0>; 182 | 183 | /* fake i2c device node */ 184 | pca9534 { 185 | compatible = "logibone"; 186 | reg = <0x24>; 187 | }; 188 | }; 189 | 190 | }; 191 | 192 | }; 193 | }; 194 | 195 | fragment@2 { 196 | target = <&spi1>; 197 | __overlay__ { 198 | 199 | #address-cells = <1>; 200 | #size-cells = <0>; 201 | status = "okay"; 202 | pinctrl-names = "default"; 203 | pinctrl-0 = <&fpga_config_pins>; 204 | ti,pio-mode; 205 | 206 | channel@0 { 207 | #address-cells = <1>; 208 | #size-cells = <0>; 209 | compatible = "spidev"; 210 | reg = <0>; 211 | spi-max-frequency = <16000000>; 212 | spi-cpha; 213 | }; 214 | }; 215 | }; 216 | }; 217 | -------------------------------------------------------------------------------- /beaglebone-black/logibone_ra2/BB-BONE-LOGIBONE-00A3_async.dts: -------------------------------------------------------------------------------- 1 | /* 2 | * Kernel 3.8.13 3 | * optargs=capemgr.disable_partno=BB-BONE-EMMC-2G 4 | * "arch/arm/boot/dts/am335x-boneblack.dts", find the section starting 5 | * with "&mmc2 {" and in section change status = "okay" into "disabled". 6 | * do once : mmc dev 1 7 | * mmc rstn 1 8 | * in uBoot or in uEnv and then delete 9 | */ 10 | 11 | /dts-v1/; 12 | /plugin/; 13 | 14 | / { 15 | compatible = "ti,beaglebone", "ti,beaglebone-black", "ti,beaglebone-green"; 16 | 17 | /* identification */ 18 | part-number = "BB-BONE-LOGIBONE"; 19 | version = "00A3"; 20 | 21 | /* state the resources this cape uses */ 22 | exclusive-use = 23 | /* the pin header uses */ 24 | "P8.25", /* gpmc: gpmc_ad0 */ 25 | "P8.24", /* gpmc: gpmc_ad1 */ 26 | "P8.5", /* gpmc: gpmc_ad2 */ 27 | "P8.6", /* gpmc: gpmc_ad3 */ 28 | "P8.23", /* gpmc: gpmc_ad4 */ 29 | "P8.22", /* gpmc: gpmc_ad5 */ 30 | "P8.3", /* gpmc: gpmc_ad6 */ 31 | "P8.4", /* gpmc: gpmc_ad7 */ 32 | "P8.19", /* gpmc: gpmc_ad8 */ 33 | "P8.13", /* gpmc: gpmc_ad9 */ 34 | "P8.14", /* gpmc: gpmc_ad10 */ 35 | "P8.17", /* gpmc: gpmc_ad11 */ 36 | "P8.12", /* gpmc: gpmc_ad12 */ 37 | "P8.11", /* gpmc: gpmc_ad13 */ 38 | "P8.16", /* gpmc: gpmc_ad14 */ 39 | "P8.15", /* gpmc: gpmc_ad15 */ 40 | "P9.12", /* gpmc: gpmc_ben1 */ 41 | "P8.21", /* gpmc: gpmc_csn1 */ 42 | "P8.18", /* gpmc: gpmc_clk */ 43 | "P8.7", /* gpmc: gpmc_advn_ale */ 44 | "P8.8", /* gpmc: gpmc_oen_ren */ 45 | "P8.10", /* gpmc: gpmc_wen */ 46 | "P8.9", /* gpmc: gpmc_ben0_cle */ 47 | "P9.28", /* BB_SPI_SS */ 48 | "P9.29", /* BB_SPI_MISO */ 49 | "P9.30", /* BB_SPI_MOSI */ 50 | "P9.31", /* BB_SPI_SCK */ 51 | "gpmc"; 52 | /*"eMMC_RSTn";*//* the reset pin */ /* uncomment for use under Kernel 3.8.13 */ 53 | 54 | #address-cells = <1>; 55 | #size-cells = <1>; 56 | 57 | fragment@0 { 58 | target = <&am33xx_pinmux>; 59 | __overlay__ { 60 | 61 | gpmc_pins: pinmux_gpmc_pins { 62 | pinctrl-single,pins = < 63 | 0x000 0x30 /* gpmc_ad0.gpmc_ad0 MODE0 | INPUT | PULLUP */ 64 | 0x004 0x30 /* gpmc_ad1.gpmc_ad1 MODE0 | INPUT | PULLUP */ 65 | 0x008 0x30 /* gpmc_ad2.gpmc_ad2 MODE0 | INPUT | PULLUP */ 66 | 0x00C 0x30 /* gpmc_ad3.gpmc_ad3 MODE0 | INPUT | PULLUP */ 67 | 0x010 0x30 /* gpmc_ad4.gpmc_ad4 MODE0 | INPUT | PULLUP */ 68 | 0x014 0x30 /* gpmc_ad5.gpmc_ad5 MODE0 | INPUT | PULLUP */ 69 | 0x018 0x30 /* gpmc_ad6.gpmc_ad6 MODE0 | INPUT | PULLUP */ 70 | 0x01C 0x30 /* gpmc_ad7.gpmc_ad7 MODE0 | INPUT | PULLUP */ 71 | 0x020 0x30 /* gpmc_ad8.gpmc_ad8 MODE0 | INPUT | PULLUP */ 72 | 0x024 0x30 /* gpmc_ad9.gpmc_ad9 MODE0 | INPUT | PULLUP */ 73 | 0x028 0x30 /* gpmc_ad10.gpmc_ad10 MODE0 | INPUT | PULLUP */ 74 | 0x02C 0x30 /* gpmc_ad11.gpmc_ad11 MODE0 | INPUT | PULLUP */ 75 | 0x030 0x30 /* gpmc_ad12.gpmc_ad12 MODE0 | INPUT | PULLUP */ 76 | 0x034 0x30 /* gpmc_ad13.gpmc_ad13 MODE0 | INPUT | PULLUP */ 77 | 0x038 0x30 /* gpmc_ad14.gpmc_ad14 MODE0 | INPUT | PULLUP */ 78 | 0x03C 0x30 /* gpmc_ad15.gpmc_ad15 MODE0 | INPUT | PULLUP */ 79 | 0x080 0x08 /* gpmc_cscn1.gpmc_cscn1 MODE0 | OUTPUT */ 80 | 0x08C 0x00 /* gpmc_clk.gpmc_clk MODE0 | OUTPUT */ 81 | 0x090 0x08 /* gpmc_advn_ale.gpmc_advn_ale MODE0 | OUTPUT */ 82 | 0x094 0x08 /* gpmc_oen_ren.gpmc_oen_ren MODE0 | OUTPUT */ 83 | 0x098 0x08 /* gpmc_wen.gpmc_wen MODE0 | OUTPUT */ 84 | 0x09C 0x08 /* gpmc_ben0_cle.gpmc_ben0_cle MODE0 | OUTPUT */ 85 | 0x078 0x08 /* gpmc_ben1_cle.gpmc_ben1_cle MODE0 | OUTPUT */ 86 | >; 87 | }; 88 | 89 | fpga_config_pins: pinmux_fpga_config_pins { 90 | pinctrl-single,pins = < 91 | /* config clk and data */ 92 | 0x198 0x37 /* spi1_d1 MODE3 | INPUT | PULLUP , serial data config */ 93 | 0x190 0x37 /* spi1_sclk MODE3 | INPUT | PULLUP, serial clock config */ 94 | >; 95 | }; 96 | }; 97 | }; 98 | 99 | fragment@1 { 100 | target = <&gpmc>; 101 | depth = <1>; /* only create devices on depth 1 */ 102 | 103 | /* stupid warnings */ 104 | #address-cells = <1>; 105 | #size-cells = <1>; 106 | 107 | __overlay__ { 108 | 109 | status = "okay"; 110 | 111 | #address-cells = <2>; 112 | #size-cells = <1>; 113 | 114 | pinctrl-names = "default"; 115 | pinctrl-0 = <&gpmc_pins>; 116 | 117 | /* chip select ranges */ 118 | ranges = <1 0 0x01000000 0x1000000>; 119 | 120 | nor { 121 | compatible = "logibone"; 122 | status = "okay"; 123 | pinctrl-names = "default"; 124 | pinctrl-0 = <&fpga_config_pins>; 125 | 126 | /*reset = <&rstctl 0 0>;*/ /* uncomment for use under Kernel 3.8.13 */ 127 | /*reset-names = "eMMC_RSTn-LOGIBONE";*/ /* uncomment for use under Kernel 3.8.13 */ 128 | 129 | reg = <1 0 0x01000000>; /*CSn1*/ 130 | 131 | bank-width = <2>; /* GPMC_CONFIG1_DEVICESIZE(1) */ 132 | 133 | gpmc,async-read; /* GPMC_CONFIG1_READTYPE_ASYNC */ 134 | gpmc,async-write; /* GPMC_CONFIG1_WRITETYPE_ASYNC */ 135 | gpmc,clk-activation-ns = <20>; /* GPMC_CONFIG1_CLKACTIVATIONTIME(2) */ 136 | gpmc,burst-length = <16>; /* GPMC_CONFIG1_PAGE_LEN(2) */ 137 | gpmc,mux-add-data = <2>; /* GPMC_CONFIG1_MUXTYPE(2) */ 138 | 139 | gpmc,sync-clk-ps = <10000>; /* CONFIG2 */ 140 | 141 | gpmc,cs-on-ns = <0>; 142 | gpmc,cs-rd-off-ns = <50>; 143 | gpmc,cs-wr-off-ns = <50>; 144 | 145 | gpmc,adv-on-ns = <0>; /* CONFIG3 */ 146 | gpmc,adv-rd-off-ns = <20>; 147 | gpmc,adv-wr-off-ns = <20>; 148 | 149 | gpmc,we-on-ns = <30>; /* CONFIG4 */ 150 | gpmc,we-off-ns = <50>; 151 | gpmc,oe-on-ns = <30>; 152 | gpmc,oe-off-ns = <50>; 153 | 154 | gpmc,page-burst-access-ns = <10>; /* CONFIG 5 */ 155 | gpmc,access-ns = <50>; 156 | gpmc,rd-cycle-ns = <60>; 157 | gpmc,wr-cycle-ns = <60>; 158 | gpmc,wr-access-ns = <0>; /* CONFIG 6 */ 159 | gpmc,wr-data-mux-bus-ns = <30>; 160 | 161 | gpmc,bus-turnaround-ns = <10>; /* CONFIG6:3:0 = 4 */ 162 | gpmc,cycle2cycle-samecsen; /* CONFIG6:7 = 1 */ 163 | gpmc,cycle2cycle-delay-ns = <10>; /* CONFIG6:11:8 = 4 */ 164 | 165 | /* not using dma engine yet, but we can get the channel number here */ 166 | dmas = <&edma 20>; 167 | dma-names = "logibone"; 168 | 169 | fpga,config { 170 | i2c-adapter = <&i2c2>; 171 | 172 | /* need it to stop the whinning */ 173 | #address-cells = <1>; 174 | #size-cells = <0>; 175 | 176 | /* fake i2c device node */ 177 | pca9534 { 178 | compatible = "logibone"; 179 | reg = <0x24>; 180 | }; 181 | }; 182 | 183 | }; 184 | 185 | }; 186 | }; 187 | 188 | fragment@2 { 189 | target = <&spi1>; 190 | __overlay__ { 191 | 192 | #address-cells = <1>; 193 | #size-cells = <0>; 194 | status = "okay"; 195 | pinctrl-names = "default"; 196 | pinctrl-0 = <&fpga_config_pins>; 197 | ti,pio-mode; 198 | 199 | channel@0 { 200 | #address-cells = <1>; 201 | #size-cells = <0>; 202 | compatible = "spidev"; 203 | reg = <0>; 204 | spi-max-frequency = <16000000>; 205 | spi-cpha; 206 | }; 207 | }; 208 | }; 209 | }; 210 | -------------------------------------------------------------------------------- /beaglebone-black/logibone_ra2/Makefile: -------------------------------------------------------------------------------- 1 | #The following definitions can be added to EXTRA_CFLAGS using -D to change the behaviour of certain modules 2 | #PROFILE: Builds modules including profiling information 3 | #USE_WORD_ADDRESSING: Enables WORD instead of BYTE addressing 4 | EXTRA_CFLAGS=-I$(PWD) -Wall -O2 5 | 6 | # If KERNELRELEASE is defined, we've been invoked from the 7 | # kernel build system and can use its language. 8 | ifneq ($(KERNELRELEASE),) 9 | obj-m := logibone_ra2_dma.o 10 | logibone_ra2_dma-objs := ../common/main_dma.o ../common/logi_dma.o config.o ioctl.o 11 | 12 | obj-m += logibone_ra2_dm.o 13 | logibone_ra2_dm-objs := ../common/main_dm.o config.o ioctl.o 14 | # Otherwise we were called directly from the command 15 | # line; invoke the kernel build system. 16 | else 17 | KERNELDIR ?= /lib/modules/$(shell uname -r)/build 18 | PWD := $(shell pwd) 19 | 20 | PHONY += default 21 | default: 22 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 23 | 24 | PHONY += clean 25 | clean: 26 | rm -f *.o *.ko .*.cmd *.mod.c *.order *.symvers ../common/*.o ../common/.*.cmd 27 | rm -rf .tmp_versions 28 | endif 29 | -------------------------------------------------------------------------------- /beaglebone-black/logibone_ra2/config.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "generic.h" 7 | #include "../common/drvr.h" 8 | 9 | 10 | //SSI 11 | #define SSI_CLK 110 12 | #define SSI_DATA 112 13 | #define SSI_DONE 3 14 | #define SSI_PROG 5 15 | #define SSI_INIT 2 16 | #define MODE0 0 17 | #define MODE1 1 18 | #define SSI_DELAY 1 19 | 20 | //GPIO 21 | #define GPIO3_BASE 0x481AE000 22 | #define GPIO3_SETDATAOUT *(gpio_regs+1) 23 | #define GPIO3_CLEARDATAOUT *(gpio_regs) 24 | 25 | //I2C 26 | #define I2C_IO_EXP_CONFIG_REG 0x03 27 | #define I2C_IO_EXP_IN_REG 0x00 28 | #define I2C_IO_EXP_OUT_REG 0x01 29 | 30 | 31 | volatile unsigned * gpio_regs; 32 | 33 | 34 | static inline void __delay_cycles(unsigned long cycles) 35 | { 36 | while (cycles != 0) { 37 | cycles--; 38 | } 39 | } 40 | 41 | static inline void ssiSetClk(void) 42 | { 43 | //gpio_set_value(SSI_CLK, 1); 44 | GPIO3_SETDATAOUT = (1 << 14); 45 | } 46 | 47 | static inline void ssiClearClk(void) 48 | { 49 | //gpio_set_value(SSI_CLK, 0); 50 | GPIO3_CLEARDATAOUT = (1 << 14); 51 | } 52 | 53 | static inline void ssiSetData(void) 54 | { 55 | //gpio_set_value(SSI_DATA, 1); 56 | GPIO3_SETDATAOUT = (1 << 16); 57 | } 58 | 59 | static inline void ssiClearData(void) 60 | { 61 | //gpio_set_value(SSI_DATA, 0); 62 | GPIO3_CLEARDATAOUT = (1 << 16); 63 | } 64 | 65 | static inline void serialConfigWriteByte(unsigned char val) 66 | { 67 | unsigned char bitCount = 0; 68 | unsigned char valBuf = val; 69 | 70 | for (bitCount = 0; bitCount < 8; bitCount++) { 71 | ssiClearClk(); 72 | 73 | if ((valBuf & 0x80) != 0) { 74 | ssiSetData(); 75 | } else { 76 | ssiClearData(); 77 | } 78 | 79 | //__delay_cycles(SSI_DELAY); 80 | ssiSetClk(); 81 | valBuf = (valBuf << 1); 82 | //__delay_cycles(SSI_DELAY); 83 | } 84 | } 85 | 86 | static inline void i2c_set_pin(struct i2c_client * io_cli, unsigned char pin, unsigned char val) 87 | { 88 | unsigned char i2c_buffer[2]; 89 | 90 | i2c_buffer[0] = I2C_IO_EXP_OUT_REG; 91 | i2c_master_send(io_cli, i2c_buffer, 1); 92 | i2c_master_recv(io_cli, &i2c_buffer[1], 1); 93 | 94 | if (val == 1) { 95 | i2c_buffer[1] |= (1 << pin); 96 | } else { 97 | i2c_buffer[1] &= ~(1 << pin); 98 | } 99 | 100 | i2c_master_send(io_cli, i2c_buffer, 2); 101 | } 102 | 103 | static inline unsigned char i2c_get_pin(struct i2c_client * io_cli, unsigned char pin) 104 | { 105 | unsigned char i2c_buffer; 106 | 107 | i2c_buffer = I2C_IO_EXP_IN_REG; 108 | i2c_master_send(io_cli, &i2c_buffer, 1); 109 | i2c_master_recv(io_cli, &i2c_buffer, 1); 110 | 111 | return ((i2c_buffer >> pin) & 0x01); 112 | } 113 | 114 | int loadBitFile(struct i2c_client * io_cli, const unsigned char * bitBuffer_user, const unsigned int length) 115 | { 116 | int res; 117 | unsigned long int i; 118 | unsigned long int timer = 0; 119 | unsigned char * bitBuffer; 120 | unsigned char i2c_buffer[4]; 121 | 122 | //request_mem_region(GPIO3_BASE + 0x190, 8, gDrvrName); 123 | gpio_regs = ioremap_nocache(GPIO3_BASE + 0x190, 2 * sizeof(int)); 124 | 125 | bitBuffer = kmalloc(length, GFP_KERNEL); 126 | 127 | if (bitBuffer == NULL) { 128 | DBG_LOG("Failed allocate buffer for configuration file\n"); 129 | 130 | return -ENOMEM; 131 | } 132 | 133 | if (copy_from_user(bitBuffer, bitBuffer_user, length)) 134 | return EFAULT; 135 | 136 | res = gpio_request(SSI_CLK, "ssi_clk"); 137 | 138 | if (res < 0) { 139 | DBG_LOG("Failed to take control over ssi_clk pin\n"); 140 | 141 | return res; 142 | } 143 | 144 | res = gpio_request(SSI_DATA, "ssi_data"); 145 | 146 | if (res < 0) { 147 | DBG_LOG("Failed to take control over ssi_data pin\n"); 148 | 149 | return res; 150 | } 151 | 152 | i2c_buffer[0] = I2C_IO_EXP_CONFIG_REG; 153 | i2c_buffer[1] = 0xFF; 154 | i2c_buffer[1] &= ~((1 << SSI_PROG) | (1 << MODE1) | (1 << MODE0)); 155 | i2c_master_send(io_cli, i2c_buffer, 2);//set SSI_PROG, MODE0, MODE1 as output others as inputs 156 | i2c_set_pin(io_cli, MODE0, 1); 157 | i2c_set_pin(io_cli, MODE1, 1); 158 | i2c_set_pin(io_cli, SSI_PROG, 0); 159 | 160 | gpio_direction_output(SSI_CLK, 0); 161 | gpio_direction_output(SSI_DATA, 0); 162 | 163 | gpio_set_value(SSI_CLK, 0); 164 | i2c_set_pin(io_cli, SSI_PROG, 1); 165 | __delay_cycles(10 * SSI_DELAY); 166 | i2c_set_pin(io_cli, SSI_PROG, 0); 167 | __delay_cycles(5 * SSI_DELAY); 168 | 169 | while (i2c_get_pin(io_cli, SSI_INIT) > 0 && timer < 200) 170 | timer++;//waiting for init pin to go down 171 | 172 | if (timer >= 200) { 173 | DBG_LOG("FPGA did not answer to prog request, init pin not going low\n"); 174 | i2c_set_pin(io_cli, SSI_PROG, 1); 175 | gpio_free(SSI_CLK); 176 | gpio_free(SSI_DATA); 177 | 178 | return -EIO; 179 | } 180 | 181 | timer = 0; 182 | __delay_cycles(5 * SSI_DELAY); 183 | i2c_set_pin(io_cli, SSI_PROG, 1); 184 | 185 | while (i2c_get_pin(io_cli, SSI_INIT) == 0 && timer < 256) {//need to find a better way ... 186 | timer++;//waiting for init pin to go up 187 | } 188 | 189 | if (timer >= 256) { 190 | DBG_LOG("FPGA did not answer to prog request, init pin not going high\n"); 191 | gpio_free(SSI_CLK); 192 | gpio_free(SSI_DATA); 193 | 194 | return -EIO; 195 | } 196 | 197 | timer = 0; 198 | DBG_LOG("Starting configuration of %d bits\n", length * 8); 199 | 200 | for (i = 0; i < length; i++) { 201 | serialConfigWriteByte(bitBuffer[i]); 202 | schedule(); 203 | } 204 | 205 | DBG_LOG("Waiting for done pin to go high\n"); 206 | 207 | while (timer < 50) { 208 | ssiClearClk(); 209 | __delay_cycles(SSI_DELAY); 210 | ssiSetClk(); 211 | __delay_cycles(SSI_DELAY); 212 | timer++; 213 | } 214 | 215 | gpio_set_value(SSI_CLK, 0); 216 | gpio_set_value(SSI_DATA, 1); 217 | 218 | if (i2c_get_pin(io_cli, SSI_DONE) == 0) { 219 | DBG_LOG("FPGA prog failed, done pin not going high\n"); 220 | gpio_free(SSI_CLK); 221 | gpio_free(SSI_DATA); 222 | 223 | return -EIO; 224 | } 225 | 226 | i2c_buffer[0] = I2C_IO_EXP_CONFIG_REG; 227 | i2c_buffer[1] = 0xDC; 228 | i2c_master_send(io_cli, i2c_buffer, 2);//set all unused config pins as input (keeping mode pins and PROG as output) 229 | gpio_direction_input(SSI_CLK); 230 | gpio_direction_input(SSI_DATA); 231 | gpio_free(SSI_CLK); 232 | gpio_free(SSI_DATA); 233 | iounmap(gpio_regs); 234 | //release_mem_region(GPIO3_BASE + 0x190, 8); 235 | kfree(bitBuffer); 236 | 237 | return length; 238 | } 239 | -------------------------------------------------------------------------------- /beaglebone-black/logibone_ra2/config.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_H__ 2 | #define __CONFIG_H__ 3 | 4 | #include 5 | #include 6 | 7 | // /dev/i2c-1 is only available in Kernel 3.8.13 which is a bug (https://github.com/RobertCNelson/bb-kernel/issues/20) 8 | #if LINUX_VERSION_CODE > KERNEL_VERSION(3,8,13) 9 | #define I2C_ADAPTER 2 10 | #else 11 | #define I2C_ADAPTER 1 12 | #endif 13 | 14 | 15 | int loadBitFile(struct i2c_client * io_cli, const unsigned char * bitBuffer_user, const unsigned int length); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /beaglebone-black/logibone_ra2/generic.h: -------------------------------------------------------------------------------- 1 | #define DEVICE_NAME "logibone" 2 | #define DEVICE_NAME_MEM "logibone_mem" 3 | 4 | //I2C 5 | #define I2C_IO_EXP_ADDR 0x24 6 | 7 | //FPGA 8 | #define FPGA_BASE_ADDR 0x01000000 9 | #define FPGA_MEM_SIZE 131072 10 | 11 | #define MAX_DMA_TRANSFER_IN_BYTES (32768) 12 | -------------------------------------------------------------------------------- /beaglebone-black/logibone_ra2/ioctl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include /* copy_to_user */ 5 | #include "ioctl.h" 6 | #include "../common/drvr.h" 7 | 8 | 9 | long ioctl_init() { 10 | return 0; 11 | } 12 | 13 | void ioctl_exit() { 14 | } 15 | 16 | long dm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){ 17 | printk("ioctl failed \n"); 18 | 19 | return -ENOTTY; 20 | } 21 | -------------------------------------------------------------------------------- /beaglebone-black/logibone_ra2/ioctl.h: -------------------------------------------------------------------------------- 1 | #ifndef __IOCTL_H__ 2 | #define __IOCTL_H__ 3 | 4 | #include 5 | #include 6 | 7 | #define MAJOR_NUM 100 8 | 9 | long ioctl_init(void); 10 | void ioctl_exit(void); 11 | long dm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); 12 | 13 | #endif 14 | 15 | 16 | -------------------------------------------------------------------------------- /beaglebone-black/logibone_ra2/setup_device-tree_RA2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | CAPE_MNGR="$(ls /sys/devices/ | grep bone_capemgr)" 4 | 5 | if [ -z "$CAPE_MNGR" ]; then 6 | SLOTS=/sys/devices/platform/bone_capemgr/slots 7 | else 8 | SLOTS=/sys/devices/$CAPE_MNGR/slots 9 | fi 10 | 11 | rm /lib/firmware/BB-BONE-LOGIBONE-00A$1.dtbo 12 | dtc -O dtb -o BB-BONE-LOGIBONE-00A$1.dtbo -b 0 -@ BB-BONE-LOGIBONE-00A$1.dts 13 | cp BB-BONE-LOGIBONE-00A$1.dtbo /lib/firmware 14 | 15 | #sh -c "echo -4 > ${SLOTS}" 16 | #sh -c "echo -5 > ${SLOTS}" 17 | #sh -c "echo -6 > ${SLOTS}" 18 | sh -c "echo BB-BONE-LOGIBONE:00A3 > ${SLOTS}" 19 | 20 | cat ${SLOTS} 21 | 22 | insmod logibone_ra$1_dm.ko 23 | -------------------------------------------------------------------------------- /old/beaglebone-black/logibone_ra1/BB-BONE-LOGIBONE-00A1.dts: -------------------------------------------------------------------------------- 1 | /* 2 | * optargs=capemgr.disable_partno=BB-BONE-EMMC-2G 3 | * "arch/arm/boot/dts/am335x-boneblack.dts", find the section starting 4 | * with "&mmc2 {" and in section change status = "okay" into "disabled". 5 | * do once : mmc dev 1 6 | * mmc rstn 1 7 | * in uBoot or in uEnv and then delete 8 | */ 9 | 10 | 11 | 12 | /dts-v1/; 13 | /plugin/; 14 | 15 | / { 16 | compatible = "ti,beaglebone", "ti,beaglebone-black"; 17 | 18 | /* identification */ 19 | part-number = "BB-BONE-LOGIBONE"; 20 | version = "00A1"; 21 | 22 | /* state the resources this cape uses */ 23 | exclusive-use = 24 | /* the pin header uses */ 25 | "P8.25", /* gpmc: gpmc_ad0 */ 26 | "P8.24", /* gpmc: gpmc_ad1 */ 27 | "P8.5", /* gpmc: gpmc_ad2 */ 28 | "P8.6", /* gpmc: gpmc_ad3 */ 29 | "P8.23", /* gpmc: gpmc_ad4 */ 30 | "P8.22", /* gpmc: gpmc_ad5 */ 31 | "P8.3", /* gpmc: gpmc_ad6 */ 32 | "P8.4", /* gpmc: gpmc_ad7 */ 33 | "P8.19", /* gpmc: gpmc_ad8 */ 34 | "P8.13", /* gpmc: gpmc_ad9 */ 35 | "P8.14", /* gpmc: gpmc_ad10 */ 36 | "P8.17", /* gpmc: gpmc_ad11 */ 37 | "P8.12", /* gpmc: gpmc_ad12 */ 38 | "P8.11", /* gpmc: gpmc_ad13 */ 39 | "P8.16", /* gpmc: gpmc_ad14 */ 40 | "P8.15", /* gpmc: gpmc_ad15 */ 41 | "P9.13", /* gpmc: gpmc_wpn */ 42 | "P8.21", /* gpmc: gpmc_csn1 */ 43 | "P8.18", /* gpmc: gpmc_clk */ 44 | "P8.7", /* gpmc: gpmc_advn_ale */ 45 | "P8.8", /* gpmc: gpmc_oen_ren */ 46 | "P8.10", /* gpmc: gpmc_wen */ 47 | "P8.9", /* gpmc: gpmc_ben0_cle */ 48 | 49 | "gpmc", 50 | /* the reset pin */ 51 | "eMMC_RSTn"; 52 | 53 | #address-cells = <1>; 54 | #size-cells = <1>; 55 | 56 | fragment@0 { 57 | target = <&am33xx_pinmux>; 58 | __overlay__ { 59 | 60 | gpmc_pins: pinmux_gpmc_pins { 61 | pinctrl-single,pins = < 62 | 0x000 0x20 /* gpmc_ad0.gpmc_ad0 MODE0 | INPUT | PULLUP */ 63 | 0x004 0x20 /* gpmc_ad1.gpmc_ad1 MODE0 | INPUT | PULLUP */ 64 | 0x008 0x20 /* gpmc_ad2.gpmc_ad2 MODE0 | INPUT | PULLUP */ 65 | 0x00C 0x20 /* gpmc_ad3.gpmc_ad3 MODE0 | INPUT | PULLUP */ 66 | 0x010 0x20 /* gpmc_ad4.gpmc_ad4 MODE0 | INPUT | PULLUP */ 67 | 0x014 0x20 /* gpmc_ad5.gpmc_ad5 MODE0 | INPUT | PULLUP */ 68 | 0x018 0x20 /* gpmc_ad6.gpmc_ad6 MODE0 | INPUT | PULLUP */ 69 | 0x01C 0x20 /* gpmc_ad7.gpmc_ad7 MODE0 | INPUT | PULLUP */ 70 | 0x020 0x20 /* gpmc_ad8.gpmc_ad8 MODE0 | INPUT | PULLUP */ 71 | 0x024 0x20 /* gpmc_ad9.gpmc_ad9 MODE0 | INPUT | PULLUP */ 72 | 0x028 0x20 /* gpmc_ad10.gpmc_ad10 MODE0 | INPUT | PULLUP */ 73 | 0x02C 0x20 /* gpmc_ad11.gpmc_ad11 MODE0 | INPUT | PULLUP */ 74 | 0x030 0x20 /* gpmc_ad12.gpmc_ad12 MODE0 | INPUT | PULLUP */ 75 | 0x034 0x20 /* gpmc_ad13.gpmc_ad13 MODE0 | INPUT | PULLUP */ 76 | 0x038 0x20 /* gpmc_ad14.gpmc_ad14 MODE0 | INPUT | PULLUP */ 77 | 0x03C 0x20 /* gpmc_ad15.gpmc_ad15 MODE0 | INPUT | PULLUP */ 78 | 0x080 0x20 /* gpmc_cscn1.gpmc_cscn1 MODE0 | OUTPUT */ 79 | 0x08C 0x00 /* gpmc_clk.gpmc_clk MODE0 | OUTPUT */ 80 | 0x090 0x00 /* gpmc_advn_ale.gpmc_advn_ale MODE0 | OUTPUT */ 81 | 0x094 0x20 /* gpmc_oen_ren.gpmc_oen_ren MODE0 | OUTPUT */ 82 | 0x098 0x20 /* gpmc_wen.gpmc_wen MODE0 | OUTPUT */ 83 | 0x09C 0x20 /* gpmc_ben0_cle.gpmc_ben0_cle MODE0 | OUTPUT */ 84 | 0x078 0x20 /* gpmc_ben1_cle.gpmc_ben1_cle MODE0 | OUTPUT */ 85 | >; 86 | }; 87 | 88 | fpga_config_pins: pinmux_fpga_config_pins { 89 | pinctrl-single,pins = < 90 | /*MODE pins*/ 91 | 0x0B4 0x17 /* lcd_data_6 MODE7 | OUTPUT, MODE0 */ 92 | 0x0BC 0x17 /* lcd_data_6 MODE7 | OUTPUT, MODE1 */ 93 | /* config init */ 94 | 0x0B8 0x17 /* lcd_data_6 MODE7 | OUTPUT, CFG_PROG_B */ 95 | 0x0B0 0x37 /* lcd_data_4 MODE7 | INPUT, CFG_INIT_B */ 96 | 0x0A8 0x37 /* lcd_data_2 MODE7 | INPUT, CFG_DONE */ 97 | 98 | /* config clk and data */ 99 | 0x158 0x17 /* spi1_d1 MODE7 | INPUT | PULLUP , serial data config */ 100 | 0x150 0x17 /* spi1_sclk MODE7 | INPUT | PULLUP, serial clock config */ 101 | >; 102 | }; 103 | }; 104 | }; 105 | 106 | fragment@1 { 107 | target = <&gpmc>; 108 | depth = <1>; /* only create devices on depth 1 */ 109 | 110 | /* stupid warnings */ 111 | #address-cells = <1>; 112 | #size-cells = <1>; 113 | 114 | __overlay__ { 115 | 116 | status = "okay"; 117 | 118 | #address-cells = <2>; 119 | #size-cells = <1>; 120 | 121 | pinctrl-names = "default"; 122 | pinctrl-0 = <&gpmc_pins>; 123 | 124 | /* chip select ranges */ 125 | ranges = <1 0 0x01000000 0x1000000>; 126 | 127 | nor { 128 | compatible = "logibone"; 129 | status = "okay"; 130 | pinctrl-names = "default"; 131 | pinctrl-0 = <&fpga_config_pins>; 132 | 133 | reset = <&rstctl 0 0>; 134 | reset-names = "eMMC_RSTn-LOGIBONE"; 135 | 136 | reg = <1 0 0x01000000>; /*CSn1*/ 137 | 138 | bank-width = <2>; /* GPMC_CONFIG1_DEVICESIZE(1) */ 139 | 140 | gpmc,async-read; /* GPMC_CONFIG1_READTYPE_ASYNC */ 141 | gpmc,async-write; /* GPMC_CONFIG1_WRITETYPE_ASYNC */ 142 | gpmc,clk-activation-ns = <20>; /* GPMC_CONFIG1_CLKACTIVATIONTIME(2) */ 143 | gpmc,burst-length = <16>; /* GPMC_CONFIG1_PAGE_LEN(2) */ 144 | gpmc,mux-add-data = <2>; /* GPMC_CONFIG1_MUXTYPE(2) */ 145 | 146 | gpmc,sync-clk-ps = <10000>; /* CONFIG2 */ 147 | 148 | gpmc,cs-on-ns = <0>; 149 | gpmc,cs-rd-off-ns = <50>; 150 | gpmc,cs-wr-off-ns = <50>; 151 | 152 | gpmc,adv-on-ns = <0>; /* CONFIG3 */ 153 | gpmc,adv-rd-off-ns = <20>; 154 | gpmc,adv-wr-off-ns = <20>; 155 | 156 | gpmc,we-on-ns = <30>; /* CONFIG4 */ 157 | gpmc,we-off-ns = <50>; 158 | gpmc,oe-on-ns = <30>; 159 | gpmc,oe-off-ns = <50>; 160 | 161 | gpmc,page-burst-access-ns = <10>; /* CONFIG 5 */ 162 | gpmc,access-ns = <50>; 163 | gpmc,rd-cycle-ns = <60>; 164 | gpmc,wr-cycle-ns = <60>; 165 | gpmc,wr-access-ns = <0>; /* CONFIG 6 */ 166 | gpmc,wr-data-mux-bus-ns = <30>; 167 | 168 | gpmc,bus-turnaround-ns = <10>; /* CONFIG6:3:0 = 4 */ 169 | gpmc,cycle2cycle-samecsen; /* CONFIG6:7 = 1 */ 170 | gpmc,cycle2cycle-delay-ns = <10>; /* CONFIG6:11:8 = 4 */ 171 | 172 | /* not using dma engine yet, but we can get the channel number here */ 173 | dmas = <&edma 20>; 174 | dma-names = "logibone"; 175 | 176 | }; 177 | 178 | }; 179 | }; 180 | 181 | fragment@2 { 182 | target = <&ocp>; 183 | 184 | __overlay__ { 185 | 186 | status = "okay"; 187 | /* avoid stupid warning */ 188 | #address-cells = <2>; 189 | #size-cells = <1>; 190 | 191 | 192 | fpga_config: ssi_config{ 193 | compatible = "bone-pinmux-helper"; 194 | pinctrl-names = "default"; 195 | pinctrl-0 = <&fpga_config_pins>; 196 | status="okay"; 197 | 198 | gpio@1 { 199 | label = "ssi_done"; 200 | gpios = <&gpio3 8 0>; 201 | }; 202 | 203 | gpio@2 { 204 | label = "ssi_prog"; 205 | gpios = <&gpio3 12 0>; 206 | }; 207 | 208 | gpio@3 { 209 | label = "ssi_init"; 210 | gpios = <&gpio3 10 0>; 211 | }; 212 | 213 | gpio@4 { 214 | label = "ssi_clk"; 215 | gpios = <&gpio1 2 0>; 216 | }; 217 | 218 | gpio@5 { 219 | label = "ssi_data"; 220 | gpios = <&gpio1 4 0>; 221 | }; 222 | 223 | gpio@6 { 224 | label = "ssi_mode0"; 225 | gpios = <&gpio3 11 1>; 226 | }; 227 | 228 | gpio@7 { 229 | label = "ssi_mode1"; 230 | gpios = <&gpio2 13 1>; 231 | }; 232 | 233 | }; 234 | 235 | }; 236 | }; 237 | 238 | }; 239 | 240 | -------------------------------------------------------------------------------- /old/beaglebone-black/logibone_ra1/Makefile: -------------------------------------------------------------------------------- 1 | # If KERNELRELEASE is defined, we've been invoked from the 2 | # kernel build system and can use its language. 3 | ifneq ($(KERNELRELEASE),) 4 | obj-m := logibone_ra1.o 5 | obj-m += logibone_ra1_dm.o 6 | 7 | # Otherwise we were called directly from the command 8 | # line; invoke the kernel build system. 9 | else 10 | KERNELDIR ?= /lib/modules/$(shell uname -r)/build 11 | PWD := $(shell pwd) 12 | default: 13 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 14 | endif 15 | 16 | clean: 17 | rm *.o *.ko .*.cmd *.order *.symvers 18 | -------------------------------------------------------------------------------- /old/beaglebone-black/logibone_ra1/logibone_ra1_dm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include /* copy_to_user */ 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | //device tree support 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | 28 | #define SSI_CLK 02 29 | #define SSI_DATA 04 30 | #define SSI_DONE 72 31 | #define SSI_PROG 76 32 | #define SSI_INIT 74 33 | 34 | 35 | #define FPGA_BASE_ADDR 0x01000000 36 | #define MEM_SIZE 131072 37 | 38 | #define DEVICE_NAME "logibone" 39 | 40 | 41 | static char * gDrvrName = DEVICE_NAME; 42 | static unsigned char gDrvrMajor = 0 ; 43 | 44 | unsigned char * readBuffer ; 45 | unsigned char * writeBuffer ; 46 | 47 | 48 | static int LOGIBONE_dm_open(struct inode *inode, struct file *filp); 49 | static int LOGIBONE_dm_release(struct inode *inode, struct file *filp); 50 | static ssize_t LOGIBONE_dm_write(struct file *filp, const char *buf, size_t count, 51 | loff_t *f_pos); 52 | static ssize_t LOGIBONE_dm_read(struct file *filp, char *buf, size_t count, loff_t *f_pos); 53 | static long LOGIBONE_dm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); 54 | 55 | 56 | 57 | static struct file_operations LOGIBONE_dm_ops = { 58 | .read = LOGIBONE_dm_read, 59 | .write = LOGIBONE_dm_write, 60 | .compat_ioctl = LOGIBONE_dm_ioctl, 61 | .unlocked_ioctl = LOGIBONE_dm_ioctl, 62 | .open = LOGIBONE_dm_open, 63 | .release = LOGIBONE_dm_release, 64 | }; 65 | 66 | enum logibone_type{ 67 | prog, 68 | mem 69 | }; 70 | 71 | struct logibone_prog{ 72 | unsigned int dummy ; 73 | }; 74 | 75 | 76 | struct logibone_mem{ 77 | unsigned short * base_addr ; 78 | unsigned short * virt_addr ; 79 | }; 80 | 81 | union logibone_data{ 82 | struct logibone_prog prog; 83 | struct logibone_mem mem; 84 | }; 85 | 86 | struct logibone_device{ 87 | enum logibone_type type ; 88 | union logibone_data data ; 89 | struct cdev cdev; 90 | unsigned char opened ; 91 | }; 92 | 93 | 94 | struct device * prog_device ; 95 | struct class * logibone_class ; 96 | struct logibone_device * logibone_devices ; 97 | 98 | 99 | int loadBitFile(const unsigned char * bitBuffer_user, unsigned int length); 100 | 101 | 102 | 103 | 104 | #define SSI_DELAY 1 105 | inline void __delay_cycles(unsigned long cycles){ 106 | while(cycles != 0){ 107 | cycles -- ; 108 | } 109 | } 110 | 111 | 112 | inline void serialConfigWriteByte(unsigned char val){ 113 | unsigned char bitCount = 0 ; 114 | unsigned char valBuf = val ; 115 | for(bitCount = 0 ; bitCount < 8 ; bitCount ++){ 116 | gpio_set_value(SSI_CLK, 0); 117 | if((valBuf & 0x80) != 0){ 118 | gpio_set_value(SSI_DATA, 1); 119 | }else{ 120 | gpio_set_value(SSI_DATA, 0); 121 | } 122 | //__delay_cycles(SSI_DELAY); 123 | gpio_set_value(SSI_CLK, 1); 124 | valBuf = (valBuf << 1); 125 | //__delay_cycles(SSI_DELAY); 126 | } 127 | } 128 | 129 | 130 | int loadBitFile(const unsigned char * bitBuffer_user, const unsigned int length){ 131 | unsigned char cfg = 1 ; 132 | unsigned long int i ; 133 | unsigned long int timer = 0; 134 | unsigned char * bitBuffer ; 135 | 136 | bitBuffer = kmalloc(length, GFP_KERNEL); 137 | if(bitBuffer == NULL || copy_from_user(bitBuffer, bitBuffer_user, length)){ 138 | printk("Failed allocate buffer for configuration file \n"); 139 | return -ENOTTY; 140 | } 141 | 142 | cfg = gpio_request(SSI_CLK, "ssi_clk"); 143 | if(cfg < 0){ 144 | printk("Failed to take control over ssi_clk pin \n"); 145 | return -ENOTTY; 146 | } 147 | cfg = gpio_request(SSI_DATA, "ssi_data"); 148 | if(cfg < 0){ 149 | printk("Failed to take control over ssi_data pin \n"); 150 | return -ENOTTY; 151 | } 152 | cfg = gpio_request(SSI_PROG, "ssi_prog"); 153 | if(cfg < 0){ 154 | printk("Failed to take control over ssi_prog pin \n"); 155 | return -ENOTTY; 156 | } 157 | cfg = gpio_request(SSI_INIT, "ssi_init"); 158 | if(cfg < 0){ 159 | printk("Failed to take control over ssi_init pin \n"); 160 | return -ENOTTY; 161 | } 162 | cfg = gpio_request(SSI_DONE, "ssi_done"); 163 | if(cfg < 0){ 164 | printk("Failed to take control over ssi_done pin \n"); 165 | return -ENOTTY; 166 | } 167 | 168 | 169 | gpio_direction_output(SSI_CLK, 0); 170 | gpio_direction_output(SSI_DATA, 0); 171 | gpio_direction_output(SSI_PROG, 0); 172 | 173 | gpio_direction_input(SSI_INIT); 174 | gpio_direction_input(SSI_DONE); 175 | 176 | gpio_set_value(SSI_CLK, 0); 177 | gpio_set_value(SSI_PROG, 1); 178 | __delay_cycles(10*SSI_DELAY); 179 | gpio_set_value(SSI_PROG, 0); 180 | __delay_cycles(5*SSI_DELAY); 181 | while(gpio_get_value(SSI_INIT) > 0 && timer < 200) timer ++; // waiting for init pin to go down 182 | if(timer >= 200){ 183 | printk("FPGA did not answer to prog request, init pin not going low \n"); 184 | gpio_set_value(SSI_PROG, 1); 185 | return -ENOTTY; 186 | } 187 | timer = 0; 188 | __delay_cycles(5*SSI_DELAY); 189 | gpio_set_value(SSI_PROG, 1); 190 | while(gpio_get_value(SSI_INIT) == 0 && timer < 0xFFFFFF){ 191 | timer ++; // waiting for init pin to go up 192 | } 193 | if(timer >= 0xFFFFFF){ 194 | printk("FPGA did not answer to prog request, init pin not going high \n"); 195 | return -ENOTTY; 196 | } 197 | timer = 0; 198 | printk("Starting configuration of %d bits \n", length*8); 199 | for(i = 0 ; i < length ; i ++){ 200 | serialConfigWriteByte(bitBuffer[i]); 201 | schedule(); 202 | } 203 | printk("Waiting for done pin to go high \n"); 204 | while(timer < 50 && gpio_get_value(SSI_DONE) == 0){ 205 | gpio_set_value(SSI_CLK, 0); 206 | __delay_cycles(SSI_DELAY); 207 | gpio_set_value(SSI_CLK, 1); 208 | __delay_cycles(SSI_DELAY); 209 | timer ++ ; 210 | } 211 | gpio_set_value(SSI_CLK, 0); 212 | gpio_set_value(SSI_DATA, 1); 213 | if(gpio_get_value(SSI_DONE) == 0 && timer >= 255){ 214 | printk("FPGA prog failed, done pin not going high \n"); 215 | return -ENOTTY; 216 | } 217 | 218 | gpio_free(SSI_CLK); 219 | gpio_free(SSI_DATA); 220 | gpio_free(SSI_PROG); 221 | gpio_free(SSI_INIT); 222 | gpio_free(SSI_DONE); 223 | 224 | kfree(bitBuffer) ; 225 | return length ; 226 | } 227 | 228 | 229 | ssize_t writeMem(struct file *filp, const char *buf, size_t count, 230 | loff_t *f_pos) 231 | { 232 | unsigned short sBuf ; 233 | struct logibone_mem * mem_to_write = &(((struct logibone_device *) filp->private_data)->data.mem) ; 234 | if(count == 2){ 235 | if(copy_from_user(&sBuf, buf, count)) return -1 ; 236 | mem_to_write->virt_addr[(*f_pos)/2] = sBuf ; 237 | return count ; 238 | } 239 | if (copy_from_user((void *) &(mem_to_write->virt_addr[(*f_pos)/2]), buf, count) ) { 240 | return -1 ; 241 | } 242 | return count; 243 | } 244 | 245 | 246 | ssize_t readMem(struct file *filp, char *buf, size_t count, loff_t *f_pos) 247 | { 248 | struct logibone_mem * mem_to_read = &(((struct logibone_device *) filp->private_data)->data.mem) ; 249 | if (copy_to_user(buf, (void *) &(mem_to_read->virt_addr[(*f_pos)/2]), count) ) { 250 | return -1 ; 251 | } 252 | return count; 253 | } 254 | 255 | 256 | 257 | static int LOGIBONE_dm_open(struct inode *inode, struct file *filp) 258 | { 259 | struct logibone_device * dev ; 260 | struct logibone_mem * mem_dev ; 261 | dev = container_of(inode->i_cdev, struct logibone_device, cdev); 262 | filp->private_data = dev; /* for other methods */ 263 | if(dev == NULL){ 264 | printk("Failed to retrieve logibone structure !\n"); 265 | return -1 ; 266 | } 267 | if(dev->opened == 1){ 268 | printk("%s: module already opened\n", gDrvrName); 269 | return 0 ; 270 | } 271 | 272 | if(dev->type == prog){ 273 | 274 | }else{ 275 | mem_dev = &((dev->data).mem) ; 276 | request_mem_region((unsigned long) mem_dev->base_addr, MEM_SIZE, gDrvrName); 277 | mem_dev->virt_addr = ioremap_nocache(((unsigned long) mem_dev->base_addr), MEM_SIZE); 278 | printk("mem interface opened \n"); 279 | } 280 | dev->opened = 1 ; 281 | return 0; 282 | } 283 | 284 | static int LOGIBONE_dm_release(struct inode *inode, struct file *filp) 285 | { 286 | struct logibone_device * dev ; 287 | dev = container_of(inode->i_cdev, struct logibone_device, cdev); 288 | if(dev->opened == 0){ 289 | printk("%s: module already released\n", gDrvrName); 290 | return 0 ; 291 | } 292 | if(dev->type == mem){ 293 | iounmap((dev->data.mem).virt_addr); 294 | release_mem_region(((unsigned long) (dev->data.mem).base_addr), MEM_SIZE ); 295 | printk("%s: Release: module released\n",gDrvrName); 296 | } 297 | dev->opened = 0 ; 298 | return 0; 299 | } 300 | 301 | 302 | static ssize_t LOGIBONE_dm_write(struct file *filp, const char *buf, size_t count, 303 | loff_t *f_pos) 304 | { 305 | struct logibone_device * dev ; 306 | dev = filp->private_data ; /* for other methods */ 307 | switch(dev->type){ 308 | case prog : 309 | 310 | return loadBitFile(buf, count); 311 | case mem: 312 | return writeMem(filp, buf, count, f_pos); 313 | default: 314 | return loadBitFile( buf, count); 315 | }; 316 | 317 | } 318 | 319 | 320 | static ssize_t LOGIBONE_dm_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) 321 | { 322 | struct logibone_device * dev ; 323 | dev = filp->private_data ; /* for other methods */ 324 | switch(dev->type){ 325 | case prog : 326 | return -1; 327 | case mem: 328 | return readMem(filp, buf, count, f_pos); 329 | default: 330 | return -1 ; 331 | }; 332 | } 333 | 334 | 335 | static long LOGIBONE_dm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){ 336 | printk("ioctl failed \n"); 337 | return -ENOTTY; 338 | } 339 | 340 | 341 | 342 | static void LOGIBONE_dm_exit(void) 343 | { 344 | int i; 345 | dev_t devno = MKDEV(gDrvrMajor, 0); 346 | /* Get rid of our char dev entries */ 347 | if (logibone_devices) { 348 | for (i = 0; i < 2; i++) { 349 | device_destroy(logibone_class, MKDEV(gDrvrMajor, i)); 350 | cdev_del(&logibone_devices[i].cdev); 351 | } 352 | kfree(logibone_devices); 353 | } 354 | class_destroy(logibone_class); 355 | /* cleanup_module is never called if registering failed */ 356 | unregister_chrdev_region(devno, 2); 357 | } 358 | 359 | static int LOGIBONE_dm_init(void) 360 | { 361 | 362 | int result; 363 | int devno ; 364 | struct logibone_mem * memDev ; 365 | struct logibone_prog * progDev ; 366 | dev_t dev = 0; 367 | result = alloc_chrdev_region(&dev, 0, 2, 368 | gDrvrName); 369 | gDrvrMajor = MAJOR(dev); 370 | if (result < 0) { 371 | printk(KERN_ALERT "Registering char device failed with %d\n", gDrvrMajor); 372 | return result; 373 | } 374 | logibone_devices = kmalloc(2 * sizeof(struct logibone_device), GFP_KERNEL); 375 | if (! logibone_devices) { 376 | result = -ENOMEM; 377 | goto fail; /* Make this more graceful */ 378 | } 379 | 380 | logibone_class = class_create(THIS_MODULE,DEVICE_NAME); 381 | 382 | memset(logibone_devices, 0, 2 * sizeof(struct logibone_device)); 383 | 384 | /*Initializing main mdevice for prog*/ 385 | devno = MKDEV(gDrvrMajor, 0); 386 | logibone_devices[0].type = prog ; 387 | progDev = &(logibone_devices[0].data.prog); 388 | prog_device = device_create(logibone_class, NULL, devno, NULL, DEVICE_NAME); // should create /dev entry for main node 389 | logibone_devices[0].opened = 0 ; 390 | 391 | 392 | if(prog_device == NULL){ 393 | class_destroy(logibone_class); 394 | result = -ENOMEM; 395 | logibone_devices[0].opened = 0 ; 396 | goto fail; 397 | } 398 | cdev_init(&(logibone_devices[0].cdev), &LOGIBONE_dm_ops); 399 | logibone_devices[0].cdev.owner = THIS_MODULE; 400 | logibone_devices[0].cdev.ops = &LOGIBONE_dm_ops; 401 | cdev_add(&(logibone_devices[0].cdev), devno, 1); 402 | //printk(KERN_INFO "'mknod /dev/%s c %d %d'.\n", gDrvrName, gDrvrMajor, 0); 403 | /* Initialize each device. */ 404 | devno = MKDEV(gDrvrMajor, 1); 405 | logibone_devices[1].type = mem ; 406 | memDev = &(logibone_devices[1].data.mem); 407 | memDev->base_addr = (unsigned short *) (FPGA_BASE_ADDR); 408 | device_create(logibone_class, prog_device, devno, NULL, "logibone_mem"); 409 | cdev_init(&(logibone_devices[1].cdev), &LOGIBONE_dm_ops); 410 | (logibone_devices[1].cdev).owner = THIS_MODULE; 411 | (logibone_devices[1].cdev).ops = &LOGIBONE_dm_ops; 412 | cdev_add(&(logibone_devices[1].cdev), devno, 1); 413 | logibone_devices[1].opened = 0 ; 414 | return 0 ; 415 | fail: 416 | LOGIBONE_dm_exit(); 417 | return -1 ; 418 | 419 | } 420 | 421 | static const struct of_device_id logibone_of_match[] = { 422 | { .compatible = "logibone", }, 423 | { }, 424 | }; 425 | MODULE_DEVICE_TABLE(of, logibone_of_match); 426 | 427 | 428 | MODULE_LICENSE("Dual BSD/GPL"); 429 | MODULE_AUTHOR("Jonathan Piat "); 430 | 431 | module_init(LOGIBONE_dm_init); 432 | module_exit(LOGIBONE_dm_exit); 433 | -------------------------------------------------------------------------------- /old/beaglebone-black/logibone_ra1/setup_device-tree_RA1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | CAPE_MNGR="$(ls /sys/devices/ | grep bone_capemgr)" 4 | 5 | rm /lib/firmware/BB-BONE-LOGIBONE-00A$1.dtbo 6 | dtc -O dtb -o BB-BONE-LOGIBONE-00A$1.dtbo -b 0 -@ BB-BONE-LOGIBONE-00A$1.dts 7 | cp BB-BONE-LOGIBONE-00A$1.dtbo /lib/firmware 8 | sh -c "echo -4 > /sys/devices/"${CAPE_MNGR}"/slots " 9 | sh -c "echo -5 > /sys/devices/"${CAPE_MNGR}"/slots " 10 | sh -c "echo -6 > /sys/devices/"${CAPE_MNGR}"/slots " 11 | sh -c "echo BB-BONE-LOGIBONE:00A1 > /sys/devices/"${CAPE_MNGR}"/slots " 12 | cat /sys/devices/"${CAPE_MNGR}"/slots 13 | insmod logibone_ra$1_dm.ko 14 | -------------------------------------------------------------------------------- /old/beaglebone/modules/edma_fifo_module/Makefile: -------------------------------------------------------------------------------- 1 | # If KERNELRELEASE is defined, we've been invoked from the 2 | # kernel build system and can use its language. 3 | ifneq ($(KERNELRELEASE),) 4 | obj-m := logibone_edma_fifo.o 5 | # Otherwise we were called directly from the command 6 | # line; invoke the kernel build system. 7 | else 8 | KERNELDIR ?= /lib/modules/$(shell uname -r)/build 9 | PWD := $(shell pwd) 10 | default: 11 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 12 | endif 13 | -------------------------------------------------------------------------------- /old/beaglebone/modules/edma_fifo_module/build_module.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- KERNELDIR=~/development/KERNEL/ARM/beaglebone/kernels/ti33x-psp-3.1/ 3 | -------------------------------------------------------------------------------- /old/beaglebone/modules/edma_fifo_module/logibone_edma_fifo.mod.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | MODULE_INFO(vermagic, VERMAGIC_STRING); 6 | 7 | struct module __this_module 8 | __attribute__((section(".gnu.linkonce.this_module"))) = { 9 | .name = KBUILD_MODNAME, 10 | .init = init_module, 11 | #ifdef CONFIG_MODULE_UNLOAD 12 | .exit = cleanup_module, 13 | #endif 14 | .arch = MODULE_ARCH_INIT, 15 | }; 16 | 17 | static const struct modversion_info ____versions[] 18 | __used 19 | __attribute__((section("__versions"))) = { 20 | { 0x81a2bdc0, "module_layout" }, 21 | { 0x1b7d45c7, "cdev_add" }, 22 | { 0xba270f6b, "cdev_init" }, 23 | { 0x29537c9e, "alloc_chrdev_region" }, 24 | { 0x91451015, "__register_chrdev" }, 25 | { 0xd6b8e852, "request_threaded_irq" }, 26 | { 0x11f447ce, "__gpio_to_irq" }, 27 | { 0x65d6d0f0, "gpio_direction_input" }, 28 | { 0x47229b5c, "gpio_request" }, 29 | { 0xb8aa2342, "__check_region" }, 30 | { 0xe9ce8b95, "omap_ioremap" }, 31 | { 0xadf42bd5, "__request_region" }, 32 | { 0x788fe103, "iomem_resource" }, 33 | { 0x9bce482f, "__release_region" }, 34 | { 0x15331242, "omap_iounmap" }, 35 | { 0xfa2a45e, "__memzero" }, 36 | { 0xfbc74f64, "__copy_from_user" }, 37 | { 0x7b513701, "dma_free_coherent" }, 38 | { 0x67c2fa54, "__copy_to_user" }, 39 | { 0x15f9fe64, "dma_alloc_coherent" }, 40 | { 0xa31e44ba, "edma_free_channel" }, 41 | { 0x3635439, "edma_stop" }, 42 | { 0x1000e51, "schedule" }, 43 | { 0x83d70683, "edma_start" }, 44 | { 0x61e1850a, "edma_write_slot" }, 45 | { 0x85737519, "edma_read_slot" }, 46 | { 0xf1e0b260, "edma_set_transfer_params" }, 47 | { 0xcaddbd7e, "edma_set_dest_index" }, 48 | { 0xf7271948, "edma_set_src_index" }, 49 | { 0x9276ce28, "edma_set_dest" }, 50 | { 0x9bda4bb4, "edma_set_src" }, 51 | { 0xfefb6077, "edma_alloc_channel" }, 52 | { 0x6bc3fbc0, "__unregister_chrdev" }, 53 | { 0xf20dabd8, "free_irq" }, 54 | { 0xfe990052, "gpio_free" }, 55 | { 0x27e1a049, "printk" }, 56 | { 0xefd6cf06, "__aeabi_unwind_cpp_pr0" }, 57 | }; 58 | 59 | static const char __module_depends[] 60 | __used 61 | __attribute__((section(".modinfo"))) = 62 | "depends="; 63 | 64 | -------------------------------------------------------------------------------- /old/beaglebone/modules/edma_fifo_module/soc_AM335x.h: -------------------------------------------------------------------------------- 1 | /** ============================================================================ 2 | * \file soc_AM33XX.h 3 | * 4 | * \brief This file contains the peripheral information for AM33XX SoC 5 | * 6 | * ============================================================================ 7 | */ 8 | 9 | /* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 10 | * ALL RIGHTS RESERVED 11 | */ 12 | 13 | #ifndef _SOC_AM33XX_H_ 14 | #define _SOC_AM33XX_H_ 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | /** @brief Base address of AINTC memory mapped registers */ 21 | #define SOC_AINTC_REGS (0x48200000) 22 | 23 | /** @brief Base addresses of UART memory mapped registers */ 24 | #define SOC_UART_0_REGS (0x44E09000) 25 | #define SOC_UART_1_REGS (0x48022000) 26 | #define SOC_UART_2_REGS (0x48024000) 27 | #define SOC_UART_3_REGS (0x481A6000) 28 | #define SOC_UART_4_REGS (0x481A8000) 29 | #define SOC_UART_5_REGS (0x481AA000) 30 | 31 | /** @brief Base addresses of USB memory mapped registers */ 32 | #define SOC_USB_0_BASE (0x47401400) 33 | #define SOC_USB_1_BASE (0x47401C00) 34 | /** @brief Base addresses of SPI memory mapped registers */ 35 | #define SOC_SPI_0_REGS (0x48030000) 36 | #define SOC_SPI_1_REGS (0x481A0000) 37 | 38 | /** @brief Base addresses of GPIO memory mapped registers */ 39 | #define SOC_GPIO_0_REGS (0x44E07000) 40 | #define SOC_GPIO_1_REGS (0x4804C000) 41 | #define SOC_GPIO_2_REGS (0x481AC000) 42 | #define SOC_GPIO_3_REGS (0x481AE000) 43 | 44 | /** @brief Base addresses of DMTIMER memory mapped registers */ 45 | #define SOC_DMTIMER_0_REGS (0x44E05000) 46 | #define SOC_DMTIMER_1_REGS (0x44E31000) 47 | #define SOC_DMTIMER_2_REGS (0x48040000) 48 | #define SOC_DMTIMER_3_REGS (0x48042000) 49 | #define SOC_DMTIMER_4_REGS (0x48044000) 50 | #define SOC_DMTIMER_5_REGS (0x48046000) 51 | #define SOC_DMTIMER_6_REGS (0x48048000) 52 | #define SOC_DMTIMER_7_REGS (0x4804A000) 53 | 54 | /** @brief Base address of MMC memory mapped registers */ 55 | #define SOC_MMCHS_0_REGS (0x48060000) 56 | #define SOC_MMCHS_1_REGS (0x481D8000) 57 | #define SOC_MMCHS_2_REGS (0x47810000) 58 | 59 | /** @brief Base address of GPMC memory mapped registers */ 60 | #define SOC_GPMC_0_REGS (0x50000000) 61 | 62 | /** @brief Base address of GPMC memory mapped registers */ 63 | #define SOC_ELM_0_REGS (0x48080000) 64 | 65 | /** @brief Base address of I2C memory mapped registers */ 66 | #define SOC_I2C_0_REGS (0x44E0B000) 67 | #define SOC_I2C_1_REGS (0x4802A000) 68 | #define SOC_I2C_2_REGS (0x4819C000) 69 | 70 | /** @brief Base address of WDT memory mapped registers */ 71 | #define SOC_WDT_0_REGS (0x44E33000) 72 | #define SOC_WDT_1_REGS (0x44E35000) 73 | 74 | /** @brief Base address of WDT memory mapped registers */ 75 | #define SOC_CPSW_SS_REGS (0x4A100000) 76 | #define SOC_CPSW_MDIO_REGS (0x4A101000) 77 | #define SOC_CPSW_WR_REGS (0x4A101200) 78 | #define SOC_CPSW_CPDMA_REGS (0x4A100800) 79 | #define SOC_CPSW_ALE_REGS (0x4A100D00) 80 | #define SOC_CPSW_STAT_REGS (0x4A100900) 81 | #define SOC_CPSW_PORT_0_REGS (0x4A100100) 82 | #define SOC_CPSW_PORT_1_REGS (0x4A100200) 83 | #define SOC_CPSW_SLIVER_1_REGS (0x4A100D80) 84 | #define SOC_CPSW_PORT_2_REGS (0x4A100300) 85 | #define SOC_CPSW_SLIVER_2_REGS (0x4A100DC0) 86 | #define SOC_CPSW_CPPI_RAM_REGS (0x4A102000) 87 | 88 | /** @brief Base address of McASP memory mapped registers */ 89 | #define SOC_MCASP_1_CTRL_REGS (0x4803C000) 90 | #define SOC_MCASP_1_FIFO_REGS (SOC_MCASP_1_CTRL_REGS + 0x1000) 91 | #define SOC_MCASP_1_DATA_REGS (0x46400000) 92 | 93 | /** @brief Base address of EMIF memory mapped registers */ 94 | #define SOC_EMIF_0_REGS (0x4C000000) 95 | 96 | /** @brief Base addresses of RTC memory mapped registers */ 97 | #define SOC_RTC_0_REGS (0x44E3E000) 98 | 99 | /** @brief Base addresses of PRCM memory mapped registers */ 100 | #define SOC_PRCM_REGS (0x44E00000) 101 | #define SOC_CM_PER_REGS (SOC_PRCM_REGS + 0) 102 | #define SOC_CM_WKUP_REGS (SOC_PRCM_REGS + 0x400) 103 | #define SOC_CM_DPLL_REGS (SOC_PRCM_REGS + 0x500) 104 | #define SOC_CM_MPU_REGS (SOC_PRCM_REGS + 0x600) 105 | #define SOC_CM_DEVICE_REGS (SOC_PRCM_REGS + 0x700) 106 | #define SOC_CM_RTC_REGS (SOC_PRCM_REGS + 0x800) 107 | #define SOC_CM_GFX_REGS (SOC_PRCM_REGS + 0x900) 108 | #define SOC_CM_CEFUSE_REGS (SOC_PRCM_REGS + 0xA00) 109 | #define SOC_OCP_SOCKET_RAM_REGS (SOC_PRCM_REGS + 0xB00) 110 | #define SOC_PRM_PER_REGS (SOC_PRCM_REGS + 0xC00) 111 | #define SOC_PRM_WKUP_REGS (SOC_PRCM_REGS + 0xD00) 112 | #define SOC_PRM_MPU_REGS (SOC_PRCM_REGS + 0xE00) 113 | #define SOC_PRM_DEVICE_REGS (SOC_PRCM_REGS + 0xF00) 114 | #define SOC_PRM_RTC_REGS (SOC_PRCM_REGS + 0x1000) 115 | #define SOC_PRM_GFX_REGS (SOC_PRCM_REGS + 0x1100) 116 | #define SOC_PRM_CEFUSE_REGS (SOC_PRCM_REGS + 0x1200) 117 | 118 | /** @brief Base address of control module memory mapped registers */ 119 | #define SOC_CONTROL_REGS (0x44E10000) 120 | 121 | 122 | /** @brief Base address of Channel controller memory mapped registers */ 123 | #define SOC_EDMA30CC_0_REGS (0x49000000) 124 | 125 | /** @brief Base address of DCAN module memory mapped registers */ 126 | #define SOC_DCAN_0_REGS (0x481CC000) 127 | #define SOC_DCAN_1_REGS (0x481D0000) 128 | 129 | /******************************************************************************\ 130 | * Parameterizable Configuration:- These are fed directly from the RTL 131 | * parameters for the given SOC 132 | \******************************************************************************/ 133 | #define TPCC_MUX(n) 0xF90 + ((n) * 4) 134 | 135 | 136 | #define SOC_LCDC_0_REGS 0x4830E000 137 | 138 | #define SOC_ADC_TSC_0_REGS 0x44E0D000 139 | 140 | /** @brief Base addresses of PWMSS memory mapped registers. */ 141 | 142 | #define SOC_PWMSS0_REGS (0x48300000) 143 | #define SOC_PWMSS1_REGS (0x48302000) 144 | #define SOC_PWMSS2_REGS (0x48304000) 145 | 146 | #define SOC_ECAP_REGS (0x00000100) 147 | #define SOC_EQEP_REGS (0x00000180) 148 | #define SOC_EPWM_REGS (0x00000200) 149 | 150 | #define SOC_ECAP_0_REGS (SOC_PWMSS0_REGS + SOC_ECAP_REGS) 151 | #define SOC_ECAP_1_REGS (SOC_PWMSS1_REGS + SOC_ECAP_REGS) 152 | #define SOC_ECAP_2_REGS (SOC_PWMSS2_REGS + SOC_ECAP_REGS) 153 | 154 | #define SOC_EQEP_0_REGS (SOC_PWMSS0_REGS + SOC_EQEP_REGS) 155 | #define SOC_EQEP_1_REGS (SOC_PWMSS1_REGS + SOC_EQEP_REGS) 156 | #define SOC_EQEP_2_REGS (SOC_PWMSS2_REGS + SOC_EQEP_REGS) 157 | 158 | #define SOC_EPWM_0_REGS (SOC_PWMSS0_REGS + SOC_EPWM_REGS) 159 | #define SOC_EPWM_1_REGS (SOC_PWMSS1_REGS + SOC_EPWM_REGS) 160 | #define SOC_EPWM_2_REGS (SOC_PWMSS2_REGS + SOC_EPWM_REGS) 161 | 162 | 163 | #define SOC_PWM0_SUB_SYS_CLOCK_CONFIG_REGS 0x48300008 164 | #define SOC_PWM0_SUB_SYS_CLOCK_STATUS_REGS 0x4830000C 165 | #define SOC_PWM0_SUB_SYS_SYS_CONFIG_REGS 0x48300004 166 | 167 | #define SOC_PWM1_SUB_SYS_CLOCK_CONFIG_REGS 0x48302008 168 | #define SOC_PWM1_SUB_SYS_CLOCK_STATUS_REGS 0x4830200C 169 | #define SOC_PWM1_SUB_SYS_SYS_CONFIG_REGS 0x48302004 170 | 171 | #define SOC_PWM2_SUB_SYS_CLOCK_CONFIG_REGS 0x48304008 172 | #define SOC_PWM2_SUB_SYS_CLOCK_STATUS_REGS 0x4830400C 173 | #define SOC_PWM2_SUB_SYS_SYS_CONFIG_REGS 0x48304004 174 | 175 | 176 | #define SOC_EPWM_MODULE_FREQ 100 177 | 178 | #ifdef __cplusplus 179 | } 180 | #endif 181 | 182 | #endif /* _SOC_AM1808_H_ */ 183 | -------------------------------------------------------------------------------- /old/beaglebone/modules/fifo_module/Makefile: -------------------------------------------------------------------------------- 1 | # If KERNELRELEASE is defined, we've been invoked from the 2 | # kernel build system and can use its language. 3 | ifneq ($(KERNELRELEASE),) 4 | obj-m := logibone_fifo.o 5 | # Otherwise we were called directly from the command 6 | # line; invoke the kernel build system. 7 | else 8 | KERNELDIR ?= /lib/modules/$(shell uname -r)/build 9 | PWD := $(shell pwd) 10 | default: 11 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 12 | endif 13 | -------------------------------------------------------------------------------- /old/beaglebone/modules/fifo_module/build_module.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | CC_PATH=/home/jpiat/development/KERNEL/ARM/beaglebone/toolchain/arm-2011.03/bin/ 3 | make ARCH=arm CROSS_COMPILE=${CC_PATH}arm-none-linux-gnueabi- KERNELDIR=~/development/KERNEL/ARM/beaglebone/kernels/ti33x-psp-3.1/ 4 | -------------------------------------------------------------------------------- /old/beaglebone/modules/fifo_module/logibone_fifo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include /* copy_to_user */ 9 | #include 10 | #include 11 | #include 12 | 13 | #include "hw_cm_per.h" 14 | #include "hw_gpmc.h" 15 | #include "soc_AM335x.h" 16 | 17 | /* 18 | #define CS_ON 0 19 | #define CS_OFF 7 20 | #define ADV_ON 0 21 | #define ADV_OFF 2 22 | #define WR_CYC 7 23 | #define WR_ON 3 24 | #define WR_OFF ((CS_ON + CS_OFF)-WR_ON) 25 | #define RD_CYC 7 26 | #define OE_ON 3 27 | #define OE_OFF ((CS_ON + CS_OFF)-OE_ON) 28 | #define RD_ACC_TIME 6 29 | #define WRDATAONADMUX 3 //number of cycle before taking control of data bus (when add/data multiplexing) 30 | 31 | 32 | // <--7--> 33 | //CS1 \_______/ 34 | // <-2>_____ 35 | //ADV \__/ 36 | // ____ <-4-> 37 | //WR \___/ 38 | // ____ <-4-> 39 | //WR \___/ 40 | */ 41 | // following settings were also tested and proved to work (faster) 42 | 43 | #define CS_ON 0 44 | #define CS_OFF 4 45 | #define ADV_ON 0 46 | #define ADV_OFF 1 47 | #define WR_CYC 5 48 | #define WR_ON 2 49 | #define WR_OFF ((CS_ON + CS_OFF)-WR_ON) 50 | #define RD_CYC 5 51 | #define OE_ON 2 52 | #define OE_OFF ((CS_ON + CS_OFF)-OE_ON) 53 | #define RD_ACC_TIME 4 54 | #define WRDATAONADMUX 2 //number of cycle before taking control of data bus (when add/data multiplexing) 55 | 56 | 57 | // <--4--> 58 | //CS1 \_______/ 59 | // <-1>_____ 60 | //ADV \__/ 61 | // ____ <-2-> 62 | //WR \___/ 63 | // ____ <-2-> 64 | //WR \___/ 65 | 66 | 67 | 68 | 69 | 70 | /* Use 'p' as magic number */ 71 | #define LOGIBONE_FIFO_IOC_MAGIC 'p' 72 | /* Please use a different 8-bit number in your code */ 73 | #define LOGIBONE_FIFO_RESET _IO(LOGIBONE_FIFO_IOC_MAGIC, 0) 74 | 75 | 76 | #define LOGIBONE_FIFO_PEEK _IOR(LOGIBONE_FIFO_IOC_MAGIC, 1, short) 77 | #define LOGIBONE_FIFO_NB_FREE _IOR(LOGIBONE_FIFO_IOC_MAGIC, 2, short) 78 | #define LOGIBONE_FIFO_NB_AVAILABLE _IOR(LOGIBONE_FIFO_IOC_MAGIC, 3, short) 79 | #define LOGIBONE_FIFO_MODE _IO(LOGIBONE_FIFO_IOC_MAGIC, 4) 80 | #define LOGIBONE_DIRECT_MODE _IO(LOGIBONE_FIFO_IOC_MAGIC, 5) 81 | 82 | 83 | //writing to fifo A reading from fifo B 84 | 85 | #define FPGA_BASE_ADDR 0x09000000 86 | #define FIFO_BASE_ADDR 0x00000000 87 | #define FIFO_CMD_OFFSET 0x0400 88 | #define FIFO_SIZE_OFFSET (FIFO_CMD_OFFSET) 89 | #define FIFO_NB_AVAILABLE_A_OFFSET (FIFO_CMD_OFFSET + 1) 90 | #define FIFO_NB_AVAILABLE_B_OFFSET (FIFO_CMD_OFFSET + 2) 91 | #define FIFO_PEEK_OFFSET (FIFO_CMD_OFFSET + 3) 92 | #define FIFO_READ_OFFSET 0 93 | #define FIFO_WRITE_OFFSET 0 94 | #define FIFO_BLOCK_SIZE 1024 //512 * 16 bits 95 | 96 | 97 | #define ACCESS_SIZE 4 // fifo read write register is on 2 bits address space to allow 4 word burst 98 | 99 | 100 | 101 | char * gDrvrName = "LOGIBONE_fifo"; 102 | unsigned char gDrvrMajor = 246 ; 103 | unsigned char gDrvrMinor = 0 ; 104 | unsigned char nbDevices = 1 ; 105 | 106 | volatile unsigned short * gpmc_cs1_pointer ; 107 | 108 | 109 | int setupGPMCClock(void) ; 110 | int setupGPMCNonMuxed(void) ; 111 | unsigned short int getNbFree(void); 112 | unsigned short int getNbAvailable(void); 113 | 114 | 115 | unsigned char * readBuffer ; 116 | unsigned char * writeBuffer ; 117 | 118 | enum LOGIBONE_fifo_read_mode{ 119 | fifo, 120 | direct 121 | } read_mode; 122 | 123 | unsigned int fifo_size ; 124 | 125 | 126 | void orShortRegister(unsigned short int value, volatile unsigned int * port){ 127 | unsigned short oldVal ; 128 | oldVal = ioread32(port); 129 | iowrite32(oldVal | value, port); 130 | } 131 | 132 | int setupGPMCClock(void){ 133 | volatile unsigned int * prcm_reg_pointer ; 134 | printk("Configuring Clock for GPMC \n"); 135 | if (check_mem_region(SOC_PRCM_REGS + CM_PER_GPMC_CLKCTRL/4, 4)) { 136 | printk("%s: memory already in use\n", gDrvrName); 137 | return -EBUSY; 138 | } 139 | request_mem_region(SOC_PRCM_REGS + CM_PER_GPMC_CLKCTRL, 4, gDrvrName); 140 | 141 | 142 | prcm_reg_pointer = ioremap_nocache(SOC_PRCM_REGS + CM_PER_GPMC_CLKCTRL, sizeof(int)); 143 | //enable clock to GPMC module 144 | 145 | orShortRegister(CM_PER_GPMC_CLKCTRL_MODULEMODE_ENABLE, prcm_reg_pointer); 146 | //check to see if enabled 147 | printk("CM_PER_GPMC_CLKCTRL value :%x \n",ioread32(prcm_reg_pointer)); 148 | while((ioread32(prcm_reg_pointer) & 149 | CM_PER_GPMC_CLKCTRL_IDLEST) != (CM_PER_GPMC_CLKCTRL_IDLEST_FUNC << CM_PER_GPMC_CLKCTRL_IDLEST_SHIFT)); 150 | printk("GPMC clock is running \n"); 151 | iounmap(prcm_reg_pointer); 152 | release_mem_region(SOC_PRCM_REGS + CM_PER_GPMC_CLKCTRL/4, 4); 153 | 154 | return 1; 155 | } 156 | 157 | int setupGPMCNonMuxed(void){ 158 | unsigned int temp = 0; 159 | unsigned short int csNum = 1 ; 160 | volatile unsigned int * gpmc_reg_pointer ; 161 | 162 | printk("Configuring GPMC for non muxed access \n"); 163 | 164 | 165 | if (check_mem_region(SOC_GPMC_0_REGS, 720)) { 166 | printk("%s: memory already in use\n", gDrvrName); 167 | return -EBUSY; 168 | } 169 | request_mem_region(SOC_GPMC_0_REGS, 720, gDrvrName); 170 | gpmc_reg_pointer = ioremap_nocache(SOC_GPMC_0_REGS, 720); 171 | 172 | 173 | 174 | printk("GPMC_REVISION value :%x \n", ioread32(gpmc_reg_pointer + GPMC_REVISION/4)); 175 | 176 | orShortRegister(GPMC_SYSCONFIG_SOFTRESET, gpmc_reg_pointer + GPMC_SYSCONFIG/4 ) ; 177 | printk("Trying to reset GPMC \n"); 178 | printk("GPMC_SYSSTATUS value :%x \n", ioread32(gpmc_reg_pointer + GPMC_SYSSTATUS/4)); 179 | while((ioread32(gpmc_reg_pointer + GPMC_SYSSTATUS/4) & 180 | GPMC_SYSSTATUS_RESETDONE) == GPMC_SYSSTATUS_RESETDONE_RSTONGOING){ 181 | printk("GPMC_SYSSTATUS value :%x \n", ioread32(gpmc_reg_pointer + 182 | GPMC_SYSSTATUS/4)); 183 | } 184 | printk("GPMC reset \n"); 185 | temp = ioread32(gpmc_reg_pointer + GPMC_SYSCONFIG/4); 186 | temp &= ~GPMC_SYSCONFIG_IDLEMODE; 187 | temp |= GPMC_SYSCONFIG_IDLEMODE_NOIDLE << GPMC_SYSCONFIG_IDLEMODE_SHIFT; 188 | iowrite32(temp, gpmc_reg_pointer + GPMC_SYSCONFIG/4); 189 | iowrite32(0x00, gpmc_reg_pointer + GPMC_IRQENABLE/4) ; 190 | iowrite32(0x00, gpmc_reg_pointer + GPMC_TIMEOUT_CONTROL/4); 191 | 192 | iowrite32((0x0 | 193 | (GPMC_CONFIG1_0_DEVICESIZE_SIXTEENBITS << 194 | GPMC_CONFIG1_0_DEVICESIZE_SHIFT ) | 195 | (GPMC_CONFIG1_0_ATTACHEDDEVICEPAGELENGTH_FOUR << 196 | GPMC_CONFIG1_0_ATTACHEDDEVICEPAGELENGTH_SHIFT ) | 197 | (GPMC_CONFIG1_0_MUXADDDATA_MUX << GPMC_CONFIG1_0_MUXADDDATA_SHIFT )), 198 | gpmc_reg_pointer + GPMC_CONFIG1(csNum)/4) ; //Address/Data multiplexed 199 | 200 | 201 | iowrite32((0x0 | 202 | (CS_ON) | // CS_ON_TIME 203 | (CS_OFF << GPMC_CONFIG2_0_CSRDOFFTIME_SHIFT) | // CS_DEASSERT_RD 204 | (CS_OFF << GPMC_CONFIG2_0_CSWROFFTIME_SHIFT)), //CS_DEASSERT_WR 205 | gpmc_reg_pointer + GPMC_CONFIG2(csNum)/4) ; 206 | 207 | iowrite32((0x0 | 208 | (ADV_ON << GPMC_CONFIG3_0_ADVONTIME_SHIFT) | //ADV_ASSERT 209 | (ADV_OFF << GPMC_CONFIG3_0_ADVRDOFFTIME_SHIFT) | //ADV_DEASSERT_RD 210 | (ADV_OFF << GPMC_CONFIG3_0_ADVWROFFTIME_SHIFT)), //ADV_DEASSERT_WR 211 | gpmc_reg_pointer + GPMC_CONFIG3(csNum)/4) ; 212 | 213 | iowrite32( (0x0 | 214 | (OE_ON << GPMC_CONFIG4_0_OEONTIME_SHIFT) | //OE_ASSERT 215 | (OE_OFF << GPMC_CONFIG4_0_OEOFFTIME_SHIFT) | //OE_DEASSERT 216 | (WR_ON << GPMC_CONFIG4_0_WEONTIME_SHIFT)| //WE_ASSERT 217 | (WR_OFF << GPMC_CONFIG4_0_WEOFFTIME_SHIFT)), //WE_DEASSERT 218 | gpmc_reg_pointer + GPMC_CONFIG4(csNum)/4) ; 219 | 220 | iowrite32((0x0 | 221 | (RD_CYC << GPMC_CONFIG5_0_RDCYCLETIME_SHIFT)| //CFG_5_RD_CYCLE_TIM 222 | (WR_CYC << GPMC_CONFIG5_0_WRCYCLETIME_SHIFT)| //CFG_5_WR_CYCLE_TIM 223 | (RD_ACC_TIME << GPMC_CONFIG5_0_RDACCESSTIME_SHIFT)), // CFG_5_RD_ACCESS_TIM 224 | gpmc_reg_pointer + GPMC_CONFIG5(csNum)/4) ; 225 | 226 | iowrite32( (0x0 | 227 | (0 << GPMC_CONFIG6_0_CYCLE2CYCLESAMECSEN_SHIFT) | 228 | (0 << GPMC_CONFIG6_0_CYCLE2CYCLEDELAY_SHIFT) | //CYC2CYC_DELAY 229 | (WRDATAONADMUX << GPMC_CONFIG6_0_WRDATAONADMUXBUS_SHIFT)| //WR_DATA_ON_ADMUX 230 | (0 << GPMC_CONFIG6_0_WRACCESSTIME_SHIFT)), //CFG_6_WR_ACCESS_TIM 231 | gpmc_reg_pointer + GPMC_CONFIG6(csNum)/4) ; 232 | 233 | iowrite32(( 0x09 << GPMC_CONFIG7_0_BASEADDRESS_SHIFT) | //CFG_7_BASE_ADDR 234 | (0x1 << GPMC_CONFIG7_0_CSVALID_SHIFT) | 235 | (0x0f << GPMC_CONFIG7_0_MASKADDRESS_SHIFT), //CFG_7_MASK 236 | gpmc_reg_pointer + GPMC_CONFIG7(csNum)/4); 237 | iounmap(gpmc_reg_pointer); 238 | release_mem_region(SOC_GPMC_0_REGS, 720); 239 | return 1; 240 | } 241 | 242 | 243 | int LOGIBONE_fifo_open(struct inode *inode, struct file *filp) 244 | { 245 | read_mode = fifo ; 246 | request_mem_region(FPGA_BASE_ADDR, FIFO_BLOCK_SIZE*2 * sizeof(short), gDrvrName); 247 | gpmc_cs1_pointer = ioremap_nocache(FPGA_BASE_ADDR, FIFO_BLOCK_SIZE*2* sizeof(int)); 248 | fifo_size = gpmc_cs1_pointer[FIFO_SIZE_OFFSET] ; 249 | printk("%s: Open: module opened\n",gDrvrName); 250 | printk("fifo size : %d\n",fifo_size); 251 | return 0; 252 | } 253 | 254 | int LOGIBONE_fifo_release(struct inode *inode, struct file *filp) 255 | { 256 | printk("%s: Release: module released\n",gDrvrName); 257 | iounmap(gpmc_cs1_pointer); 258 | release_mem_region(FPGA_BASE_ADDR, FIFO_BLOCK_SIZE*2 * sizeof(short)); 259 | return 0; 260 | } 261 | 262 | 263 | unsigned short int getNbAvailable(void){ 264 | return ( gpmc_cs1_pointer[FIFO_NB_AVAILABLE_B_OFFSET]*2) ; 265 | } 266 | 267 | unsigned short int getNbFree(void){ 268 | fifo_size = gpmc_cs1_pointer[FIFO_SIZE_OFFSET] ; 269 | return ((fifo_size - gpmc_cs1_pointer[FIFO_NB_AVAILABLE_A_OFFSET])*2) ; 270 | } 271 | 272 | ssize_t LOGIBONE_fifo_write(struct file *filp, const char *buf, size_t count, 273 | loff_t *f_pos) 274 | { 275 | unsigned short int transfer_size ; 276 | ssize_t transferred = 0 ; 277 | unsigned long src_addr, trgt_addr ; 278 | unsigned int ret = 0; 279 | if(count%2 != 0){ 280 | printk("%s: LOGIBONE_fifo write: Transfer must be 16bits aligned.\n",gDrvrName); 281 | return -1; 282 | } 283 | if(count < FIFO_BLOCK_SIZE){ 284 | transfer_size = count ; 285 | }else{ 286 | transfer_size = FIFO_BLOCK_SIZE ; 287 | } 288 | writeBuffer = (unsigned char *) kmalloc (count, GFP_KERNEL); 289 | trgt_addr = (unsigned long) gpmc_cs1_pointer ; 290 | src_addr = (unsigned long) writeBuffer ; 291 | // Now it is safe to copy the data from user space. 292 | if (writeBuffer == NULL || copy_from_user(writeBuffer, buf, count) ) { 293 | ret = -1; 294 | printk("%s: LOGIBONE_fifo write: Failed copy from user.\n",gDrvrName); 295 | goto exit; 296 | } 297 | if(read_mode == fifo){ 298 | while(transferred < count){ 299 | while(getNbFree() < transfer_size) schedule() ; 300 | memcpy((void*)trgt_addr, (void*)src_addr, transfer_size); 301 | src_addr += transfer_size ; 302 | transferred += transfer_size ; 303 | if((count - transferred) < FIFO_BLOCK_SIZE){ 304 | transfer_size = count - transferred ; 305 | }else{ 306 | transfer_size = FIFO_BLOCK_SIZE ; 307 | } 308 | } 309 | ret = transferred; 310 | }else{ 311 | memcpy((void*)trgt_addr, (void*)src_addr, count); 312 | ret = count ; 313 | } 314 | exit: 315 | kfree(writeBuffer); 316 | return (ret); 317 | } 318 | 319 | 320 | ssize_t LOGIBONE_fifo_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) 321 | { 322 | unsigned short int transfer_size ; 323 | ssize_t transferred = 0 ; 324 | unsigned long src_addr, trgt_addr ; 325 | int ret = 0 ; 326 | if(count%2 != 0){ 327 | printk("%s: LOGIBONE_fifo read: Transfer must be 16bits aligned.\n",gDrvrName); 328 | return -1 ; 329 | } 330 | if(count < FIFO_BLOCK_SIZE){ 331 | transfer_size = count ; 332 | }else{ 333 | transfer_size = FIFO_BLOCK_SIZE ; 334 | } 335 | readBuffer = (unsigned char *) kmalloc (count, GFP_KERNEL); 336 | src_addr = (unsigned long) gpmc_cs1_pointer ; 337 | trgt_addr = (unsigned long) readBuffer ; 338 | if(read_mode == fifo){ 339 | while(transferred < count){ 340 | while(getNbAvailable() < transfer_size) schedule() ; 341 | memcpy((void*) trgt_addr, (void*)src_addr, transfer_size); 342 | trgt_addr += transfer_size ; 343 | transferred += transfer_size ; 344 | if((count - transferred) < FIFO_BLOCK_SIZE){ 345 | transfer_size = (count - transferred) ; 346 | }else{ 347 | transfer_size = FIFO_BLOCK_SIZE ; 348 | } 349 | } 350 | if (copy_to_user(buf, readBuffer, transferred) ) { 351 | ret = -1; 352 | goto exit; 353 | } 354 | ret = transferred ; 355 | }else{ 356 | memcpy((void*)trgt_addr, (void*)src_addr, count); 357 | 358 | if (copy_to_user(buf, readBuffer, count) ) { 359 | ret = -1; 360 | goto exit; 361 | } 362 | ret = count ; 363 | } 364 | exit: 365 | kfree(readBuffer); 366 | return ret; 367 | } 368 | 369 | long LOGIBONE_fifo_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){ 370 | 371 | switch(cmd){ 372 | case LOGIBONE_FIFO_RESET : 373 | printk("fifo ioctl : reset \n"); 374 | gpmc_cs1_pointer[FIFO_NB_AVAILABLE_A_OFFSET] = 0 ; 375 | gpmc_cs1_pointer[FIFO_NB_AVAILABLE_B_OFFSET] = 0 ; 376 | return 0 ; 377 | case LOGIBONE_FIFO_PEEK : 378 | printk("fifo ioctl : peek \n"); 379 | return gpmc_cs1_pointer[FIFO_PEEK_OFFSET] ; 380 | case LOGIBONE_FIFO_NB_FREE : 381 | printk("fifo ioctl : free \n"); 382 | return getNbFree() ; 383 | case LOGIBONE_FIFO_NB_AVAILABLE : 384 | printk("fifo ioctl : available \n"); 385 | return getNbAvailable() ; 386 | case LOGIBONE_FIFO_MODE : 387 | printk("switching to fifo mode \n"); 388 | read_mode = fifo ; 389 | return 0 ; 390 | case LOGIBONE_DIRECT_MODE : 391 | printk("switching to direct mode \n"); 392 | read_mode = direct ; 393 | return 0 ; 394 | default: /* redundant, as cmd was checked against MAXNR */ 395 | printk("unknown command %d \n", cmd); 396 | return -ENOTTY; 397 | } 398 | } 399 | 400 | struct file_operations LOGIBONE_fifo_ops = { 401 | .read = LOGIBONE_fifo_read, 402 | .write = LOGIBONE_fifo_write, 403 | .compat_ioctl = LOGIBONE_fifo_ioctl, 404 | .unlocked_ioctl = LOGIBONE_fifo_ioctl, 405 | .open = LOGIBONE_fifo_open, 406 | .release = LOGIBONE_fifo_release, 407 | }; 408 | 409 | 410 | static int LOGIBONE_fifo_init(void) 411 | { 412 | dev_t dev = 0; 413 | struct cdev cdev ; 414 | int result ; 415 | setupGPMCClock(); 416 | if(setupGPMCNonMuxed() < 0 ){ 417 | printk(KERN_WARNING "%s: can't initialize gpmc \n",gDrvrName); 418 | return -1; 419 | } 420 | 421 | if (check_mem_region(FPGA_BASE_ADDR, 256 * sizeof(short)) ){ 422 | printk("%s: memory already in use\n", gDrvrName); 423 | return -EBUSY; 424 | } 425 | 426 | 427 | if (gDrvrMajor) { 428 | dev = MKDEV(gDrvrMajor, gDrvrMinor); 429 | result = register_chrdev(gDrvrMajor, gDrvrName, &LOGIBONE_fifo_ops); 430 | } else { 431 | result = alloc_chrdev_region(&dev, gDrvrMinor, nbDevices, gDrvrName); 432 | gDrvrMajor = MAJOR(dev); 433 | cdev_init(&cdev, &LOGIBONE_fifo_ops); 434 | result = cdev_add (&cdev, MKDEV(gDrvrMajor, 0), 1); 435 | /* Fail gracefully if need be */ 436 | if (result) 437 | printk(KERN_NOTICE "Error %d adding LOGIBONE_fifo%d", result, 0); 438 | } 439 | if (result < 0) { 440 | printk(KERN_WARNING "%s: can't get major %d\n",gDrvrName,gDrvrMajor); 441 | return -1; 442 | } 443 | printk(KERN_INFO"%s: Init: module registered with major number %d \n", gDrvrName, gDrvrMajor); 444 | 445 | printk("%s driver is loaded\n", gDrvrName); 446 | 447 | return 0; 448 | } 449 | 450 | static void LOGIBONE_fifo_exit(void) 451 | { 452 | 453 | 454 | unregister_chrdev(gDrvrMajor, gDrvrName); 455 | 456 | printk(/*KERN_ALERT*/ "%s driver is unloaded\n", gDrvrName); 457 | } 458 | 459 | 460 | MODULE_LICENSE("Dual BSD/GPL"); 461 | MODULE_AUTHOR("Jonathan Piat "); 462 | 463 | module_init(LOGIBONE_fifo_init); 464 | module_exit(LOGIBONE_fifo_exit); 465 | -------------------------------------------------------------------------------- /old/beaglebone/modules/fifo_module/soc_AM335x.h: -------------------------------------------------------------------------------- 1 | /** ============================================================================ 2 | * \file soc_AM33XX.h 3 | * 4 | * \brief This file contains the peripheral information for AM33XX SoC 5 | * 6 | * ============================================================================ 7 | */ 8 | 9 | /* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 10 | * ALL RIGHTS RESERVED 11 | */ 12 | 13 | #ifndef _SOC_AM33XX_H_ 14 | #define _SOC_AM33XX_H_ 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | /** @brief Base address of AINTC memory mapped registers */ 21 | #define SOC_AINTC_REGS (0x48200000) 22 | 23 | /** @brief Base addresses of UART memory mapped registers */ 24 | #define SOC_UART_0_REGS (0x44E09000) 25 | #define SOC_UART_1_REGS (0x48022000) 26 | #define SOC_UART_2_REGS (0x48024000) 27 | #define SOC_UART_3_REGS (0x481A6000) 28 | #define SOC_UART_4_REGS (0x481A8000) 29 | #define SOC_UART_5_REGS (0x481AA000) 30 | 31 | /** @brief Base addresses of USB memory mapped registers */ 32 | #define SOC_USB_0_BASE (0x47401400) 33 | #define SOC_USB_1_BASE (0x47401C00) 34 | /** @brief Base addresses of SPI memory mapped registers */ 35 | #define SOC_SPI_0_REGS (0x48030000) 36 | #define SOC_SPI_1_REGS (0x481A0000) 37 | 38 | /** @brief Base addresses of GPIO memory mapped registers */ 39 | #define SOC_GPIO_0_REGS (0x44E07000) 40 | #define SOC_GPIO_1_REGS (0x4804C000) 41 | #define SOC_GPIO_2_REGS (0x481AC000) 42 | #define SOC_GPIO_3_REGS (0x481AE000) 43 | 44 | /** @brief Base addresses of DMTIMER memory mapped registers */ 45 | #define SOC_DMTIMER_0_REGS (0x44E05000) 46 | #define SOC_DMTIMER_1_REGS (0x44E31000) 47 | #define SOC_DMTIMER_2_REGS (0x48040000) 48 | #define SOC_DMTIMER_3_REGS (0x48042000) 49 | #define SOC_DMTIMER_4_REGS (0x48044000) 50 | #define SOC_DMTIMER_5_REGS (0x48046000) 51 | #define SOC_DMTIMER_6_REGS (0x48048000) 52 | #define SOC_DMTIMER_7_REGS (0x4804A000) 53 | 54 | /** @brief Base address of MMC memory mapped registers */ 55 | #define SOC_MMCHS_0_REGS (0x48060000) 56 | #define SOC_MMCHS_1_REGS (0x481D8000) 57 | #define SOC_MMCHS_2_REGS (0x47810000) 58 | 59 | /** @brief Base address of GPMC memory mapped registers */ 60 | #define SOC_GPMC_0_REGS (0x50000000) 61 | 62 | /** @brief Base address of GPMC memory mapped registers */ 63 | #define SOC_ELM_0_REGS (0x48080000) 64 | 65 | /** @brief Base address of I2C memory mapped registers */ 66 | #define SOC_I2C_0_REGS (0x44E0B000) 67 | #define SOC_I2C_1_REGS (0x4802A000) 68 | #define SOC_I2C_2_REGS (0x4819C000) 69 | 70 | /** @brief Base address of WDT memory mapped registers */ 71 | #define SOC_WDT_0_REGS (0x44E33000) 72 | #define SOC_WDT_1_REGS (0x44E35000) 73 | 74 | /** @brief Base address of WDT memory mapped registers */ 75 | #define SOC_CPSW_SS_REGS (0x4A100000) 76 | #define SOC_CPSW_MDIO_REGS (0x4A101000) 77 | #define SOC_CPSW_WR_REGS (0x4A101200) 78 | #define SOC_CPSW_CPDMA_REGS (0x4A100800) 79 | #define SOC_CPSW_ALE_REGS (0x4A100D00) 80 | #define SOC_CPSW_STAT_REGS (0x4A100900) 81 | #define SOC_CPSW_PORT_0_REGS (0x4A100100) 82 | #define SOC_CPSW_PORT_1_REGS (0x4A100200) 83 | #define SOC_CPSW_SLIVER_1_REGS (0x4A100D80) 84 | #define SOC_CPSW_PORT_2_REGS (0x4A100300) 85 | #define SOC_CPSW_SLIVER_2_REGS (0x4A100DC0) 86 | #define SOC_CPSW_CPPI_RAM_REGS (0x4A102000) 87 | 88 | /** @brief Base address of McASP memory mapped registers */ 89 | #define SOC_MCASP_1_CTRL_REGS (0x4803C000) 90 | #define SOC_MCASP_1_FIFO_REGS (SOC_MCASP_1_CTRL_REGS + 0x1000) 91 | #define SOC_MCASP_1_DATA_REGS (0x46400000) 92 | 93 | /** @brief Base address of EMIF memory mapped registers */ 94 | #define SOC_EMIF_0_REGS (0x4C000000) 95 | 96 | /** @brief Base addresses of RTC memory mapped registers */ 97 | #define SOC_RTC_0_REGS (0x44E3E000) 98 | 99 | /** @brief Base addresses of PRCM memory mapped registers */ 100 | #define SOC_PRCM_REGS (0x44E00000) 101 | #define SOC_CM_PER_REGS (SOC_PRCM_REGS + 0) 102 | #define SOC_CM_WKUP_REGS (SOC_PRCM_REGS + 0x400) 103 | #define SOC_CM_DPLL_REGS (SOC_PRCM_REGS + 0x500) 104 | #define SOC_CM_MPU_REGS (SOC_PRCM_REGS + 0x600) 105 | #define SOC_CM_DEVICE_REGS (SOC_PRCM_REGS + 0x700) 106 | #define SOC_CM_RTC_REGS (SOC_PRCM_REGS + 0x800) 107 | #define SOC_CM_GFX_REGS (SOC_PRCM_REGS + 0x900) 108 | #define SOC_CM_CEFUSE_REGS (SOC_PRCM_REGS + 0xA00) 109 | #define SOC_OCP_SOCKET_RAM_REGS (SOC_PRCM_REGS + 0xB00) 110 | #define SOC_PRM_PER_REGS (SOC_PRCM_REGS + 0xC00) 111 | #define SOC_PRM_WKUP_REGS (SOC_PRCM_REGS + 0xD00) 112 | #define SOC_PRM_MPU_REGS (SOC_PRCM_REGS + 0xE00) 113 | #define SOC_PRM_DEVICE_REGS (SOC_PRCM_REGS + 0xF00) 114 | #define SOC_PRM_RTC_REGS (SOC_PRCM_REGS + 0x1000) 115 | #define SOC_PRM_GFX_REGS (SOC_PRCM_REGS + 0x1100) 116 | #define SOC_PRM_CEFUSE_REGS (SOC_PRCM_REGS + 0x1200) 117 | 118 | /** @brief Base address of control module memory mapped registers */ 119 | #define SOC_CONTROL_REGS (0x44E10000) 120 | 121 | 122 | /** @brief Base address of Channel controller memory mapped registers */ 123 | #define SOC_EDMA30CC_0_REGS (0x49000000) 124 | 125 | /** @brief Base address of DCAN module memory mapped registers */ 126 | #define SOC_DCAN_0_REGS (0x481CC000) 127 | #define SOC_DCAN_1_REGS (0x481D0000) 128 | 129 | /******************************************************************************\ 130 | * Parameterizable Configuration:- These are fed directly from the RTL 131 | * parameters for the given SOC 132 | \******************************************************************************/ 133 | #define TPCC_MUX(n) 0xF90 + ((n) * 4) 134 | 135 | 136 | #define SOC_LCDC_0_REGS 0x4830E000 137 | 138 | #define SOC_ADC_TSC_0_REGS 0x44E0D000 139 | 140 | /** @brief Base addresses of PWMSS memory mapped registers. */ 141 | 142 | #define SOC_PWMSS0_REGS (0x48300000) 143 | #define SOC_PWMSS1_REGS (0x48302000) 144 | #define SOC_PWMSS2_REGS (0x48304000) 145 | 146 | #define SOC_ECAP_REGS (0x00000100) 147 | #define SOC_EQEP_REGS (0x00000180) 148 | #define SOC_EPWM_REGS (0x00000200) 149 | 150 | #define SOC_ECAP_0_REGS (SOC_PWMSS0_REGS + SOC_ECAP_REGS) 151 | #define SOC_ECAP_1_REGS (SOC_PWMSS1_REGS + SOC_ECAP_REGS) 152 | #define SOC_ECAP_2_REGS (SOC_PWMSS2_REGS + SOC_ECAP_REGS) 153 | 154 | #define SOC_EQEP_0_REGS (SOC_PWMSS0_REGS + SOC_EQEP_REGS) 155 | #define SOC_EQEP_1_REGS (SOC_PWMSS1_REGS + SOC_EQEP_REGS) 156 | #define SOC_EQEP_2_REGS (SOC_PWMSS2_REGS + SOC_EQEP_REGS) 157 | 158 | #define SOC_EPWM_0_REGS (SOC_PWMSS0_REGS + SOC_EPWM_REGS) 159 | #define SOC_EPWM_1_REGS (SOC_PWMSS1_REGS + SOC_EPWM_REGS) 160 | #define SOC_EPWM_2_REGS (SOC_PWMSS2_REGS + SOC_EPWM_REGS) 161 | 162 | 163 | #define SOC_PWM0_SUB_SYS_CLOCK_CONFIG_REGS 0x48300008 164 | #define SOC_PWM0_SUB_SYS_CLOCK_STATUS_REGS 0x4830000C 165 | #define SOC_PWM0_SUB_SYS_SYS_CONFIG_REGS 0x48300004 166 | 167 | #define SOC_PWM1_SUB_SYS_CLOCK_CONFIG_REGS 0x48302008 168 | #define SOC_PWM1_SUB_SYS_CLOCK_STATUS_REGS 0x4830200C 169 | #define SOC_PWM1_SUB_SYS_SYS_CONFIG_REGS 0x48302004 170 | 171 | #define SOC_PWM2_SUB_SYS_CLOCK_CONFIG_REGS 0x48304008 172 | #define SOC_PWM2_SUB_SYS_CLOCK_STATUS_REGS 0x4830400C 173 | #define SOC_PWM2_SUB_SYS_SYS_CONFIG_REGS 0x48304004 174 | 175 | 176 | #define SOC_EPWM_MODULE_FREQ 100 177 | 178 | #ifdef __cplusplus 179 | } 180 | #endif 181 | 182 | #endif /* _SOC_AM1808_H_ */ 183 | -------------------------------------------------------------------------------- /old/mark1/BB-BONE-MARK1-00A1.dts: -------------------------------------------------------------------------------- 1 | /* 2 | * Kernel 3.8.13 3 | * optargs=capemgr.disable_partno=BB-BONE-EMMC-2G 4 | * "arch/arm/boot/dts/am335x-boneblack.dts", find the section starting 5 | * with "&mmc2 {" and in section change status = "okay" into "disabled". 6 | * do once : mmc dev 1 7 | * mmc rstn 1 8 | * in uBoot or in uEnv and then delete 9 | */ 10 | 11 | /dts-v1/; 12 | /plugin/; 13 | 14 | / { 15 | compatible = "ti,beaglebone", "ti,beaglebone-black"; 16 | 17 | /* identification */ 18 | part-number = "BB-BONE-MARK1"; 19 | version = "00A1"; 20 | 21 | /* state the resources this cape uses */ 22 | exclusive-use = 23 | /* the pin header uses */ 24 | "P8.25", /* gpmc: gpmc_ad0 */ 25 | "P8.24", /* gpmc: gpmc_ad1 */ 26 | "P8.5", /* gpmc: gpmc_ad2 */ 27 | "P8.6", /* gpmc: gpmc_ad3 */ 28 | "P8.23", /* gpmc: gpmc_ad4 */ 29 | "P8.22", /* gpmc: gpmc_ad5 */ 30 | "P8.3", /* gpmc: gpmc_ad6 */ 31 | "P8.4", /* gpmc: gpmc_ad7 */ 32 | "P8.19", /* gpmc: gpmc_ad8 */ 33 | "P8.13", /* gpmc: gpmc_ad9 */ 34 | "P8.14", /* gpmc: gpmc_ad10 */ 35 | "P8.17", /* gpmc: gpmc_ad11 */ 36 | "P8.12", /* gpmc: gpmc_ad12 */ 37 | "P8.11", /* gpmc: gpmc_ad13 */ 38 | "P8.16", /* gpmc: gpmc_ad14 */ 39 | "P8.15", /* gpmc: gpmc_ad15 */ 40 | "P9.12", /* gpmc: gpmc_ben1 */ 41 | "P8.21", /* gpmc: gpmc_csn1 */ 42 | "P8.18", /* gpmc: gpmc_clk */ 43 | "P8.7", /* gpmc: gpmc_advn_ale */ 44 | "P8.8", /* gpmc: gpmc_oen_ren */ 45 | "P8.10", /* gpmc: gpmc_wen */ 46 | "P8.9", /* gpmc: gpmc_ben0_cle */ 47 | "P9.28", /* BB_SPI_SS */ 48 | "P9.29", /* BB_SPI_MISO */ 49 | "P9.30", /* BB_SPI_MOSI */ 50 | "P9.31", /* BB_SPI_SCK */ 51 | "gpmc", 52 | "eMMC_RSTn";/* the reset pin */ /* uncomment for use under Kernel 3.8.13 */ 53 | 54 | #address-cells = <1>; 55 | #size-cells = <1>; 56 | 57 | fragment@0 { 58 | target = <&am33xx_pinmux>; 59 | __overlay__ { 60 | 61 | gpmc_pins: pinmux_gpmc_pins { 62 | pinctrl-single,pins = < 63 | 0x000 0x30 /* gpmc_ad0.gpmc_ad0 MODE0 | INPUT | PULLUP */ 64 | 0x004 0x30 /* gpmc_ad1.gpmc_ad1 MODE0 | INPUT | PULLUP */ 65 | 0x008 0x30 /* gpmc_ad2.gpmc_ad2 MODE0 | INPUT | PULLUP */ 66 | 0x00C 0x30 /* gpmc_ad3.gpmc_ad3 MODE0 | INPUT | PULLUP */ 67 | 0x010 0x30 /* gpmc_ad4.gpmc_ad4 MODE0 | INPUT | PULLUP */ 68 | 0x014 0x30 /* gpmc_ad5.gpmc_ad5 MODE0 | INPUT | PULLUP */ 69 | 0x018 0x30 /* gpmc_ad6.gpmc_ad6 MODE0 | INPUT | PULLUP */ 70 | 0x01C 0x30 /* gpmc_ad7.gpmc_ad7 MODE0 | INPUT | PULLUP */ 71 | 0x020 0x30 /* gpmc_ad8.gpmc_ad8 MODE0 | INPUT | PULLUP */ 72 | 0x024 0x30 /* gpmc_ad9.gpmc_ad9 MODE0 | INPUT | PULLUP */ 73 | 0x028 0x30 /* gpmc_ad10.gpmc_ad10 MODE0 | INPUT | PULLUP */ 74 | 0x02C 0x30 /* gpmc_ad11.gpmc_ad11 MODE0 | INPUT | PULLUP */ 75 | 0x030 0x30 /* gpmc_ad12.gpmc_ad12 MODE0 | INPUT | PULLUP */ 76 | 0x034 0x30 /* gpmc_ad13.gpmc_ad13 MODE0 | INPUT | PULLUP */ 77 | 0x038 0x30 /* gpmc_ad14.gpmc_ad14 MODE0 | INPUT | PULLUP */ 78 | 0x03C 0x30 /* gpmc_ad15.gpmc_ad15 MODE0 | INPUT | PULLUP */ 79 | 0x080 0x08 /* gpmc_cscn1.gpmc_cscn1 MODE0 | OUTPUT */ 80 | 0x08C 0x28 /* gpmc_clk.gpmc_clk MODE0 | INPUT */ 81 | 0x090 0x08 /* gpmc_advn_ale.gpmc_advn_ale MODE0 | OUTPUT */ 82 | 0x094 0x08 /* gpmc_oen_ren.gpmc_oen_ren MODE0 | OUTPUT */ 83 | 0x098 0x08 /* gpmc_wen.gpmc_wen MODE0 | OUTPUT */ 84 | 0x09C 0x08 /* gpmc_ben0_cle.gpmc_ben0_cle MODE0 | OUTPUT */ 85 | 0x078 0x08 /* gpmc_ben1_cle.gpmc_ben1_cle MODE0 | OUTPUT */ 86 | >; 87 | }; 88 | 89 | fpga_config_pins: pinmux_fpga_config_pins { 90 | pinctrl-single,pins = < 91 | /* config clk and data */ 92 | 0x158 0x17 /* spi1_d1 MODE3 | INPUT | PULLUP , serial data config */ 93 | 0x150 0x17 /* spi1_sclk MODE3 | INPUT | PULLUP, serial clock config */ 94 | >; 95 | }; 96 | }; 97 | }; 98 | 99 | fragment@1 { 100 | target = <&gpmc>; 101 | depth = <1>; /* only create devices on depth 1 */ 102 | 103 | /* stupid warnings */ 104 | #address-cells = <1>; 105 | #size-cells = <1>; 106 | 107 | __overlay__ { 108 | 109 | status = "okay"; 110 | 111 | #address-cells = <2>; 112 | #size-cells = <1>; 113 | 114 | pinctrl-names = "default"; 115 | pinctrl-0 = <&gpmc_pins>; 116 | 117 | /* chip select ranges */ 118 | ranges = <1 0 0x01000000 0x1000000>; 119 | 120 | nor { 121 | compatible = "mark1"; 122 | status = "okay"; 123 | pinctrl-names = "default"; 124 | pinctrl-0 = <&fpga_config_pins>; 125 | 126 | reset = <&rstctl 0 0>; /* uncomment for use under Kernel 3.8.13 */ 127 | reset-names = "eMMC_RSTn-LOGIBONE"; /* uncomment for use under Kernel 3.8.13 */ 128 | 129 | reg = <1 0 0x01000000>; /*CSn1*/ 130 | 131 | bank-width = <2>; /* GPMC_CONFIG1_DEVICESIZE(1) */ 132 | 133 | gpmc,async-read; /* GPMC_CONFIG1_READTYPE_ASYNC */ 134 | gpmc,async-write; /* GPMC_CONFIG1_WRITETYPE_ASYNC */ 135 | gpmc,clk-activation-ns = <20>; /* GPMC_CONFIG1_CLKACTIVATIONTIME(2) */ 136 | gpmc,burst-length = <16>; /* GPMC_CONFIG1_PAGE_LEN(2) */ 137 | gpmc,mux-add-data = <2>; /* GPMC_CONFIG1_MUXTYPE(2) */ 138 | 139 | gpmc,sync-clk-ps = <10000>; /* CONFIG2 */ 140 | 141 | gpmc,cs-on-ns = <0>; 142 | gpmc,cs-rd-off-ns = <50>; 143 | gpmc,cs-wr-off-ns = <50>; 144 | 145 | gpmc,adv-on-ns = <0>; /* CONFIG3 */ 146 | gpmc,adv-rd-off-ns = <20>; 147 | gpmc,adv-wr-off-ns = <20>; 148 | 149 | gpmc,we-on-ns = <30>; /* CONFIG4 */ 150 | gpmc,we-off-ns = <50>; 151 | gpmc,oe-on-ns = <30>; 152 | gpmc,oe-off-ns = <50>; 153 | 154 | gpmc,page-burst-access-ns = <10>; /* CONFIG 5 */ 155 | gpmc,access-ns = <50>; 156 | gpmc,rd-cycle-ns = <60>; 157 | gpmc,wr-cycle-ns = <60>; 158 | gpmc,wr-access-ns = <0>; /* CONFIG 6 */ 159 | gpmc,wr-data-mux-bus-ns = <30>; 160 | 161 | gpmc,bus-turnaround-ns = <10>; /* CONFIG6:3:0 = 4 */ 162 | gpmc,cycle2cycle-samecsen; /* CONFIG6:7 = 1 */ 163 | gpmc,cycle2cycle-delay-ns = <10>; /* CONFIG6:11:8 = 4 */ 164 | 165 | /* not using dma engine yet, but we can get the channel number here */ 166 | dmas = <&edma 20>; 167 | dma-names = "mark1"; 168 | 169 | fpga,config { 170 | i2c-adapter = <&i2c2>; 171 | 172 | /* need it to stop the whinning */ 173 | #address-cells = <1>; 174 | #size-cells = <0>; 175 | 176 | /* fake i2c device node */ 177 | pca9534 { 178 | compatible = "mark1"; 179 | reg = <0x70>; 180 | }; 181 | }; 182 | 183 | }; 184 | 185 | }; 186 | }; 187 | 188 | fragment@2 { 189 | target = <&spi0>; 190 | __overlay__ { 191 | #address-cells = <1>; 192 | #size-cells = <0>; 193 | status = "okay"; 194 | pinctrl-names = "default"; 195 | pinctrl-0 = <&fpga_config_pins>; 196 | 197 | spi0_0{ 198 | #address-cells = <1>; 199 | #size-cells = <0>; 200 | compatible = "spidev"; 201 | reg = <0>; 202 | spi-max-frequency = <16000000>; 203 | spi-cpha; 204 | }; 205 | spi0_1{ 206 | #address-cells = <1>; 207 | #size-cells = <0>; 208 | compatible = "spidev"; 209 | reg = <1>; 210 | spi-max-frequency = <16000000>; 211 | // Mode 0 (CPOL = 0, CPHA = 0) 212 | }; 213 | }; 214 | }; 215 | 216 | 217 | }; 218 | 219 | -------------------------------------------------------------------------------- /old/mark1/BB-BONE-MARK1-00A1_sync.dts: -------------------------------------------------------------------------------- 1 | /* 2 | * optargs=capemgr.disable_partno=BB-BONE-EMMC-2G 3 | * "arch/arm/boot/dts/am335x-boneblack.dts", find the section starting 4 | * with "&mmc2 {" and in section change status = "okay" into "disabled". 5 | * do once : mmc dev 1 6 | * mmc rstn 1 7 | * in uBoot or in uEnv and then delete 8 | */ 9 | 10 | 11 | 12 | /dts-v1/; 13 | /plugin/; 14 | 15 | / { 16 | compatible = "ti,beaglebone", "ti,beaglebone-black"; 17 | 18 | /* identification */ 19 | part-number = "BB-BONE-MARK1"; 20 | version = "00A1"; 21 | 22 | /* state the resources this cape uses */ 23 | exclusive-use = 24 | /* the pin header uses */ 25 | "P8.25", /* gpmc: gpmc_ad0 */ 26 | "P8.24", /* gpmc: gpmc_ad1 */ 27 | "P8.5", /* gpmc: gpmc_ad2 */ 28 | "P8.6", /* gpmc: gpmc_ad3 */ 29 | "P8.23", /* gpmc: gpmc_ad4 */ 30 | "P8.22", /* gpmc: gpmc_ad5 */ 31 | "P8.3", /* gpmc: gpmc_ad6 */ 32 | "P8.4", /* gpmc: gpmc_ad7 */ 33 | "P8.19", /* gpmc: gpmc_ad8 */ 34 | "P8.13", /* gpmc: gpmc_ad9 */ 35 | "P8.14", /* gpmc: gpmc_ad10 */ 36 | "P8.17", /* gpmc: gpmc_ad11 */ 37 | "P8.12", /* gpmc: gpmc_ad12 */ 38 | "P8.11", /* gpmc: gpmc_ad13 */ 39 | "P8.16", /* gpmc: gpmc_ad14 */ 40 | "P8.15", /* gpmc: gpmc_ad15 */ 41 | "P9.13", /* gpmc: gpmc_wpn */ 42 | "P8.21", /* gpmc: gpmc_csn1 */ 43 | "P8.18", /* gpmc: gpmc_clk */ 44 | "P8.7", /* gpmc: gpmc_advn_ale */ 45 | "P8.8", /* gpmc: gpmc_oen_ren */ 46 | "P8.10", /* gpmc: gpmc_wen */ 47 | "P8.9", /* gpmc: gpmc_ben0_cle */ 48 | 49 | "P9.18", 50 | "P9.22", 51 | 52 | "gpmc", 53 | /* the reset pin */ 54 | "eMMC_RSTn"; 55 | 56 | #address-cells = <1>; 57 | #size-cells = <1>; 58 | 59 | fragment@0 { 60 | target = <&am33xx_pinmux>; 61 | __overlay__ { 62 | 63 | gpmc_pins: pinmux_gpmc_pins { 64 | pinctrl-single,pins = < 65 | 0x000 0x30 /* gpmc_ad0.gpmc_ad0 MODE0 | INPUT | PULLUP */ 66 | 0x004 0x30 /* gpmc_ad1.gpmc_ad1 MODE0 | INPUT | PULLUP */ 67 | 0x008 0x30 /* gpmc_ad2.gpmc_ad2 MODE0 | INPUT | PULLUP */ 68 | 0x00C 0x30 /* gpmc_ad3.gpmc_ad3 MODE0 | INPUT | PULLUP */ 69 | 0x010 0x30 /* gpmc_ad4.gpmc_ad4 MODE0 | INPUT | PULLUP */ 70 | 0x014 0x30 /* gpmc_ad5.gpmc_ad5 MODE0 | INPUT | PULLUP */ 71 | 0x018 0x30 /* gpmc_ad6.gpmc_ad6 MODE0 | INPUT | PULLUP */ 72 | 0x01C 0x30 /* gpmc_ad7.gpmc_ad7 MODE0 | INPUT | PULLUP */ 73 | 0x020 0x30 /* gpmc_ad8.gpmc_ad8 MODE0 | INPUT | PULLUP */ 74 | 0x024 0x30 /* gpmc_ad9.gpmc_ad9 MODE0 | INPUT | PULLUP */ 75 | 0x028 0x30 /* gpmc_ad10.gpmc_ad10 MODE0 | INPUT | PULLUP */ 76 | 0x02C 0x30 /* gpmc_ad11.gpmc_ad11 MODE0 | INPUT | PULLUP */ 77 | 0x030 0x30 /* gpmc_ad12.gpmc_ad12 MODE0 | INPUT | PULLUP */ 78 | 0x034 0x30 /* gpmc_ad13.gpmc_ad13 MODE0 | INPUT | PULLUP */ 79 | 0x038 0x30 /* gpmc_ad14.gpmc_ad14 MODE0 | INPUT | PULLUP */ 80 | 0x03C 0x30 /* gpmc_ad15.gpmc_ad15 MODE0 | INPUT | PULLUP */ 81 | 0x080 0x08 /* gpmc_cscn1.gpmc_cscn1 MODE0 | OUTPUT */ 82 | 0x08C 0x28 /* gpmc_clk.gpmc_clk MODE0 | OUTPUT */ 83 | 0x090 0x08 /* gpmc_advn_ale.gpmc_advn_ale MODE0 | OUTPUT */ 84 | 0x094 0x08 /* gpmc_oen_ren.gpmc_oen_ren MODE0 | OUTPUT */ 85 | 0x098 0x08 /* gpmc_wen.gpmc_wen MODE0 | OUTPUT */ 86 | 0x09C 0x08 /* gpmc_ben0_cle.gpmc_ben0_cle MODE0 | OUTPUT */ 87 | 0x078 0x08 /* gpmc_ben1_cle.gpmc_ben1_cle MODE0 | OUTPUT */ 88 | >; 89 | }; 90 | 91 | fpga_config_pins: pinmux_fpga_config_pins { 92 | pinctrl-single,pins = < 93 | /* config clk and data */ 94 | 0x158 0x17 /* spi1_d1 MODE3 | INPUT | PULLUP , serial data config */ 95 | 0x150 0x17 /* spi1_sclk MODE3 | INPUT | PULLUP, serial clock config */ 96 | >; 97 | }; 98 | }; 99 | }; 100 | 101 | fragment@1 { 102 | target = <&gpmc>; 103 | depth = <1>; /* only create devices on depth 1 */ 104 | 105 | /* stupid warnings */ 106 | #address-cells = <1>; 107 | #size-cells = <1>; 108 | 109 | __overlay__ { 110 | 111 | status = "okay"; 112 | 113 | #address-cells = <2>; 114 | #size-cells = <1>; 115 | 116 | pinctrl-names = "default"; 117 | pinctrl-0 = <&gpmc_pins>; 118 | 119 | /* chip select ranges */ 120 | ranges = <1 0 0x01000000 0x1000000>; 121 | 122 | nor { 123 | compatible = "mark1"; 124 | status = "okay"; 125 | pinctrl-names = "default"; 126 | pinctrl-0 = <&fpga_config_pins>; 127 | 128 | reset = <&rstctl 0 0>; 129 | reset-names = "eMMC_RSTn-MARK1"; 130 | 131 | reg = <1 0 0x01000000>; /*CSn1*/ 132 | 133 | bank-width = <2>; /* GPMC_CONFIG1_DEVICESIZE(1) */ 134 | 135 | /*gpmc,burst-write;*/ 136 | gpmc,burst-read; 137 | gpmc,burst-wrap; 138 | gpmc,sync-read; /* GPMC_CONFIG1_READTYPE_ASYNC */ 139 | gpmc,sync-write; /* GPMC_CONFIG1_WRITETYPE_ASYNC */ 140 | gpmc,clk-activation-ns = <0>; /* GPMC_CONFIG1_CLKACTIVATIONTIME(2) */ 141 | gpmc,burst-length = <16>; /* GPMC_CONFIG1_PAGE_LEN(2) */ 142 | gpmc,mux-add-data = <2>; /* GPMC_CONFIG1_MUXTYPE(2) */ 143 | 144 | gpmc,sync-clk-ps = <20000>; /* CONFIG2 */ 145 | 146 | gpmc,cs-on-ns = <0>; 147 | gpmc,cs-rd-off-ns = <100>; 148 | gpmc,cs-wr-off-ns = <40>; 149 | 150 | gpmc,adv-on-ns = <0>; /* CONFIG3 */ 151 | gpmc,adv-rd-off-ns = <20>; 152 | gpmc,adv-wr-off-ns = <20>; 153 | 154 | gpmc,we-on-ns = <20>; /* CONFIG4 */ 155 | gpmc,we-off-ns = <40>; 156 | gpmc,oe-on-ns = <20>; 157 | gpmc,oe-off-ns = <100>; 158 | 159 | gpmc,page-burst-access-ns = <20>; /* CONFIG 5 */ 160 | gpmc,access-ns = <80>; 161 | gpmc,rd-cycle-ns = <120>; 162 | gpmc,wr-cycle-ns = <60>; 163 | gpmc,wr-access-ns = <40>; /* CONFIG 6 */ 164 | gpmc,wr-data-mux-bus-ns = <20>; 165 | 166 | /*gpmc,bus-turnaround-ns = <40>;*/ /* CONFIG6:3:0 = 4 */ 167 | /*gpmc,cycle2cycle-samecsen;*/ /* CONFIG6:7 = 1 */ 168 | /*gpmc,cycle2cycle-delay-ns = <40>;*/ /* CONFIG6:11:8 = 4 */ 169 | 170 | /* not using dma engine yet, but we can get the channel number here */ 171 | dmas = <&edma 20>; 172 | dma-names = "mark1"; 173 | 174 | fpga,config { 175 | i2c-adapter = <&i2c2>; 176 | 177 | /* need it to stop the whinning */ 178 | #address-cells = <1>; 179 | #size-cells = <0>; 180 | 181 | /* fake i2c device node */ 182 | pca9534 { 183 | compatible = "mark1"; 184 | reg = <0x70>; 185 | }; 186 | }; 187 | 188 | }; 189 | 190 | }; 191 | }; 192 | 193 | fragment@2 { 194 | target = <&spi0>; 195 | __overlay__ { 196 | #address-cells = <1>; 197 | #size-cells = <0>; 198 | status = "okay"; 199 | pinctrl-names = "default"; 200 | pinctrl-0 = <&fpga_config_pins>; 201 | 202 | spi0_0{ 203 | #address-cells = <1>; 204 | #size-cells = <0>; 205 | compatible = "spidev"; 206 | reg = <0>; 207 | spi-max-frequency = <16000000>; 208 | spi-cpha; 209 | }; 210 | spi0_1{ 211 | #address-cells = <1>; 212 | #size-cells = <0>; 213 | compatible = "spidev"; 214 | reg = <1>; 215 | spi-max-frequency = <16000000>; 216 | // Mode 0 (CPOL = 0, CPHA = 0) 217 | }; 218 | }; 219 | }; 220 | 221 | 222 | }; 223 | 224 | -------------------------------------------------------------------------------- /old/mark1/Makefile: -------------------------------------------------------------------------------- 1 | #The following definitions can be added to EXTRA_CFLAGS using -D to change the behaviour of certain modules 2 | #PROFILE: Builds modules including profiling information 3 | #USE_WORD_ADDRESSING: Enables WORD instead of BYTE addressing 4 | EXTRA_CFLAGS=-I$(PWD) -Wall -O2 5 | 6 | # If KERNELRELEASE is defined, we've been invoked from the 7 | # kernel build system and can use its language. 8 | ifneq ($(KERNELRELEASE),) 9 | obj-m := mark1_dma.o 10 | mark1_dma-objs := ../common/main_dma.o ../common/logi_dma.o config.o ioctl.o 11 | 12 | obj-m += mark1_dm.o 13 | mark1_dm-objs := ../common/main_dm.o config.o ioctl.o 14 | # Otherwise we were called directly from the command 15 | # line; invoke the kernel build system. 16 | else 17 | KERNELDIR ?= /lib/modules/$(shell uname -r)/build 18 | PWD := $(shell pwd) 19 | 20 | PHONY += default 21 | default: 22 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 23 | 24 | PHONY += clean 25 | clean: 26 | rm -f *.o *.ko .*.cmd *.mod.c *.order *.symvers ../common/*.o ../common/.*.cmd 27 | rm -rf .tmp_versions 28 | endif 29 | -------------------------------------------------------------------------------- /old/mark1/config.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | //SSI 9 | #define SSI_CLK 02 // to be verified 10 | #define SSI_DATA 04 11 | #define SSI_DONE 0x03 12 | #define SSI_PROG 0x05 13 | #define SSI_INIT 0x06 14 | #define MODE0 0 15 | #define MODE1 1 16 | #define SSI_DELAY 300 17 | 18 | //GPIO 19 | #define GPIO0_BASE 0x44E07000 20 | #define GPIO0_SETDATAOUT *(gpio_regs+1) 21 | #define GPIO0_CLEARDATAOUT *(gpio_regs) 22 | 23 | 24 | volatile unsigned * gpio_regs; 25 | 26 | 27 | static inline void __delay_cycles(unsigned long cycles) 28 | { 29 | while (cycles != 0) { 30 | cycles--; 31 | } 32 | } 33 | 34 | static inline void ssiSetClk(void) 35 | { 36 | //gpio_set_value(SSI_CLK, 1); 37 | GPIO0_SETDATAOUT = (1 << 2); 38 | } 39 | 40 | static inline void ssiClearClk(void) 41 | { 42 | //gpio_set_value(SSI_CLK, 0); 43 | GPIO0_CLEARDATAOUT = (1 << 2); 44 | } 45 | 46 | static inline void ssiSetData(void) 47 | { 48 | //gpio_set_value(SSI_DATA, 1); 49 | GPIO0_SETDATAOUT = (1 << 4); 50 | } 51 | 52 | static inline void ssiClearData(void) 53 | { 54 | //gpio_set_value(SSI_DATA, 0); 55 | GPIO0_CLEARDATAOUT = (1 << 4); 56 | } 57 | 58 | static inline void serialConfigWriteByte(unsigned char val) 59 | { 60 | unsigned char bitCount = 0; 61 | unsigned char valBuf = val; 62 | 63 | for (bitCount = 0; bitCount < 8; bitCount++) { 64 | ssiClearClk(); 65 | 66 | if ((valBuf & 0x80) != 0) { 67 | ssiSetData(); 68 | } else { 69 | ssiClearData(); 70 | } 71 | 72 | __delay_cycles(SSI_DELAY); 73 | ssiSetClk(); 74 | valBuf = (valBuf << 1); 75 | __delay_cycles(SSI_DELAY); 76 | } 77 | } 78 | 79 | static inline void i2c_set_pin(struct i2c_client * io_cli, unsigned char pin, unsigned char val) 80 | { 81 | unsigned char i2c_buffer[2]; 82 | 83 | i2c_buffer[0] = pin; 84 | i2c_master_send(io_cli, i2c_buffer, 1); 85 | } 86 | 87 | static inline unsigned char i2c_get_pin(struct i2c_client * io_cli, unsigned char pin) 88 | { 89 | unsigned char i2c_buffer[2]; 90 | 91 | i2c_buffer[0] = pin; 92 | //i2c_master_send(io_cli, &i2c_buffer, 1); 93 | i2c_master_recv(io_cli, i2c_buffer, 2); 94 | //printk("reading value %x \n", i2c_buffer); 95 | 96 | return i2c_buffer[0]; 97 | } 98 | 99 | static inline unsigned char i2c_get_pin_ex(struct i2c_client * io_cli, unsigned char pin) 100 | { 101 | unsigned char i2c_buffer[2]; 102 | 103 | i2c_master_send(io_cli, &pin, 1); 104 | i2c_master_recv(io_cli, i2c_buffer, 2); 105 | 106 | return i2c_buffer[1]; 107 | } 108 | 109 | int loadBitFile(struct i2c_client * io_cli, const unsigned char * bitBuffer_user, const unsigned int length) 110 | { 111 | int iCfg; 112 | unsigned char i2c_test; 113 | unsigned long int i; 114 | unsigned long int timer = 0; 115 | unsigned char * bitBuffer; 116 | //unsigned char i2c_buffer[4]; 117 | 118 | //request_mem_region(GPIO0_BASE + 0x190, 8, DEVICE_NAME); 119 | gpio_regs = ioremap_nocache(GPIO0_BASE + 0x190, 2 * sizeof(int)); 120 | 121 | bitBuffer = kmalloc(length, GFP_KERNEL); 122 | 123 | if (bitBuffer == NULL || copy_from_user(bitBuffer, bitBuffer_user, length)) { 124 | printk("Failed allocate buffer for configuration file \n"); 125 | 126 | return -ENOTTY; 127 | } 128 | 129 | iCfg = gpio_request(SSI_CLK, "ssi_clk"); 130 | 131 | if (iCfg < 0) { 132 | printk("Failed to take control over ssi_clk pin \n"); 133 | 134 | return -ENOTTY; 135 | } 136 | 137 | iCfg = gpio_request(SSI_DATA, "ssi_data"); 138 | 139 | if (iCfg < 0) { 140 | printk("Failed to take control over ssi_data pin \n"); 141 | 142 | return -ENOTTY; 143 | } 144 | 145 | /*i2c_set_pin(io_cli, MODE0, 1); 146 | i2c_set_pin(io_cli, MODE1, 1); 147 | i2c_set_pin(io_cli, SSI_PROG, 0);*/ 148 | 149 | gpio_direction_output(SSI_CLK, 0); 150 | gpio_direction_output(SSI_DATA, 0); 151 | 152 | gpio_set_value(SSI_CLK, 0); 153 | //i2c_set_pin(io_cli, SSI_PROG, 1); 154 | //__delay_cycles(10*SSI_DELAY); 155 | i2c_set_pin(io_cli, SSI_PROG, 0); 156 | __delay_cycles(5 * SSI_DELAY); 157 | 158 | //wait for FPGA to successfully enter configuration mode 159 | do { 160 | i2c_test = i2c_get_pin_ex(io_cli, SSI_INIT); 161 | } while (i2c_test != 0x01 && timer++ < 100); 162 | 163 | if (timer >= 100) { 164 | printk("FPGA did not answer to prog request, init pin not going high \n"); 165 | gpio_free(SSI_CLK); 166 | gpio_free(SSI_DATA); 167 | 168 | return -ENOTTY; 169 | } 170 | 171 | //debug only 172 | printk("loop finished with 0x%x from LPC; iter=%lu\n", i2c_test, timer); 173 | 174 | timer = 0; 175 | printk("Starting configuration of %d bits \n", length * 8); 176 | 177 | for (i = 0; i < length; i++) { 178 | serialConfigWriteByte(bitBuffer[i]); 179 | schedule(); 180 | } 181 | 182 | printk("Waiting for done pin to go high \n"); 183 | 184 | while (timer < 50) { 185 | ssiClearClk(); 186 | __delay_cycles(SSI_DELAY); 187 | ssiSetClk(); 188 | __delay_cycles(SSI_DELAY); 189 | timer++; 190 | } 191 | 192 | gpio_set_value(SSI_CLK, 0); 193 | gpio_set_value(SSI_DATA, 1); 194 | 195 | if (i2c_get_pin(io_cli, SSI_DONE) == 0) { 196 | printk("FPGA prog failed, done pin not going high \n"); 197 | gpio_direction_input(SSI_CLK); 198 | gpio_direction_input(SSI_DATA); 199 | gpio_free(SSI_CLK); 200 | gpio_free(SSI_DATA); 201 | 202 | return -ENOTTY; 203 | } 204 | 205 | /*i2c_buffer[0] = I2C_IO_EXP_CONFIG_REG; 206 | i2c_buffer[1] = 0xDC; 207 | i2c_master_send(io_cli, i2c_buffer, 2); // set all unused config pins as input (keeping mode pins and PROG as output)*/ 208 | gpio_direction_input(SSI_CLK); 209 | gpio_direction_input(SSI_DATA); 210 | gpio_free(SSI_CLK); 211 | gpio_free(SSI_DATA); 212 | iounmap(gpio_regs); 213 | //release_mem_region(GPIO0_BASE + 0x190, 8); 214 | kfree(bitBuffer); 215 | 216 | return length; 217 | } 218 | 219 | -------------------------------------------------------------------------------- /old/mark1/config.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_H__ 2 | #define __CONFIG_H__ 3 | 4 | #include 5 | #include 6 | 7 | // /dev/i2c-1 is only available in Kernel 3.8.13 which is a bug (https://github.com/RobertCNelson/bb-kernel/issues/20) 8 | #if LINUX_VERSION_CODE > KERNEL_VERSION(3,8,13) 9 | #define I2C_ADAPTER 2 10 | #else 11 | #define I2C_ADAPTER 1 12 | #endif 13 | 14 | 15 | int loadBitFile(struct i2c_client * io_cli, const unsigned char * bitBuffer_user, const unsigned int length); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /old/mark1/generic.h: -------------------------------------------------------------------------------- 1 | #define DEVICE_NAME "mark1" 2 | #define DEVICE_NAME_MEM "mark1_mem" 3 | 4 | //I2C 5 | #define I2C_IO_EXP_ADDR 0x70 6 | 7 | //FPGA 8 | #define FPGA_BASE_ADDR 0x01000000 9 | #define FPGA_MEM_SIZE 131072 10 | 11 | #define MAX_DMA_TRANSFER_IN_BYTES (32768) 12 | -------------------------------------------------------------------------------- /old/mark1/ioctl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include /* copy_to_user */ 5 | #include "ioctl.h" 6 | #include "../common/drvr.h" 7 | 8 | 9 | long ioctl_init() { 10 | return 0; 11 | } 12 | 13 | void ioctl_exit() { 14 | } 15 | 16 | long dm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){ 17 | printk("ioctl failed \n"); 18 | 19 | return -ENOTTY; 20 | } 21 | -------------------------------------------------------------------------------- /old/mark1/ioctl.h: -------------------------------------------------------------------------------- 1 | #ifndef __IOCTL_H__ 2 | #define __IOCTL_H__ 3 | 4 | #include 5 | #include 6 | 7 | #define MAJOR_NUM 100 8 | 9 | long ioctl_init(void); 10 | void ioctl_exit(void); 11 | long dm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); 12 | 13 | #endif 14 | 15 | 16 | -------------------------------------------------------------------------------- /old/mark1/setup_device-tree_mark1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | CAPE_MNGR="$(ls /sys/devices/ | grep bone_capemgr)" 4 | 5 | if [ -z "$CAPE_MNGR" ]; then 6 | SLOTS=/sys/devices/platform/bone_capemgr/slots 7 | else 8 | SLOTS=/sys/devices/$CAPE_MNGR/slots 9 | fi 10 | 11 | while getopts ds opt 12 | do 13 | case $opt in 14 | d) echo "Using DMA mode" && bDma=true;; 15 | s) echo "Synchronous mode" && bSync=true;; 16 | *) echo "Unknown option specified" 17 | esac 18 | done 19 | 20 | rm /lib/firmware/BB-BONE-MARK1-00A1.dtbo 21 | 22 | if [ "$bSync" ];then 23 | dtc -O dtb -o BB-BONE-MARK1-00A1.dtbo -b 0 -@ BB-BONE-MARK1-00A1_sync.dts 24 | else 25 | dtc -O dtb -o BB-BONE-MARK1-00A1.dtbo -b 0 -@ BB-BONE-MARK1-00A1.dts 26 | fi 27 | 28 | cp BB-BONE-MARK1-00A1.dtbo /lib/firmware 29 | 30 | #sh -c "echo -4 > ${SLOTS}" 31 | #sh -c "echo -5 > ${SLOTS}" 32 | #sh -c "echo -6 > ${SLOTS}" 33 | sh -c "echo BB-BONE-MARK1:00A1 > ${SLOTS}" 34 | 35 | cat ${SLOTS} 36 | 37 | if [ "$bDma" ];then 38 | insmod mark1_dma.ko 39 | else 40 | insmod mark1_dm.ko 41 | fi 42 | --------------------------------------------------------------------------------