static void __init perseus2_init_smc91x(void) { fpga_write(1, H2P2_DBG_FPGA_LAN_RESET); mdelay(50); fpga_write(fpga_read(H2P2_DBG_FPGA_LAN_RESET) & ~1, H2P2_DBG_FPGA_LAN_RESET); mdelay(50); }
static void __init innovator_init(void) { if (cpu_is_omap1510()) omap1510_fpga_init_irq(); innovator_init_smc91x(); #ifdef CONFIG_ARCH_OMAP15XX if (cpu_is_omap1510()) { unsigned char reg; /* mux pins for uarts */ omap_cfg_reg(UART1_TX); omap_cfg_reg(UART1_RTS); omap_cfg_reg(UART2_TX); omap_cfg_reg(UART2_RTS); omap_cfg_reg(UART3_TX); omap_cfg_reg(UART3_RX); reg = fpga_read(OMAP1510_FPGA_POWER); reg |= OMAP1510_FPGA_PCR_COM1_EN; fpga_write(reg, OMAP1510_FPGA_POWER); udelay(10); reg = fpga_read(OMAP1510_FPGA_POWER); reg |= OMAP1510_FPGA_PCR_COM2_EN; fpga_write(reg, OMAP1510_FPGA_POWER); udelay(10); platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices)); spi_register_board_info(innovator1510_boardinfo, ARRAY_SIZE(innovator1510_boardinfo)); } #endif #ifdef CONFIG_ARCH_OMAP16XX if (!cpu_is_omap1510()) { platform_add_devices(innovator1610_devices, ARRAY_SIZE(innovator1610_devices)); } #endif #ifdef CONFIG_ARCH_OMAP15XX if (cpu_is_omap1510()) { omap1_usb_init(&innovator1510_usb_config); innovator_config[1].data = &innovator1510_lcd_config; } #endif #ifdef CONFIG_ARCH_OMAP16XX if (cpu_is_omap1610()) { omap1_usb_init(&h2_usb_config); innovator_config[1].data = &innovator1610_lcd_config; } #endif omap_board_config = innovator_config; omap_board_config_size = ARRAY_SIZE(innovator_config); omap_serial_init(); omap_register_i2c_bus(1, 100, NULL, 0); innovator_mmc_init(); }
static int mmc_set_power(struct device *dev, int slot, int power_on, int vdd) { if (power_on) fpga_write(fpga_read(OMAP1510_FPGA_POWER) | (1 << 3), OMAP1510_FPGA_POWER); else fpga_write(fpga_read(OMAP1510_FPGA_POWER) & ~(1 << 3), OMAP1510_FPGA_POWER); return 0; }
int device_fpgas_rw(struct device *device) { int result; int num; for (num = 0; num < device->num_of_fpgas; num++) { struct fpga *fpga = &device->fpga[num]; //if (!fpga->valid) // currently if r/w error on some FPGA, the entire device invalidated // continue; //fpga_select(fpga); // unlike select_fpga() from Ztex SDK, it waits for i/o timeout result = fpga_select_setup_io(fpga); // combines fpga_select(), fpga_get_io_state() and fpga_setup_output() in 1 USB request if (result < 0) { fprintf(stderr, "SN %s FPGA #%d fpga_select_setup_io() error: %d\n", device->ztex_device->snString, num, result); return result; } // write if (!fpga->wr.wr_count || fpga->wr.wr_done) { // FPGA-based application processes in 2-byte words, don't write unaligned int len = 2* (random() % (max_len+1 - min_len)/2) + min_len; fpga->wr.len = len; fpga->data_out = buf_set(fpga->wr.buf, fpga->wr.len, fpga->data_out); } result = fpga_write(fpga); if (result < 0) { fprintf(stderr, "SN %s FPGA #%d write error: %d (%s)\n", device->ztex_device->snString, num, result, libusb_strerror(result)); fpga->valid = 0; return result; } if (result > 0) { wr_byte_count += fpga->wr.len; if ( wr_byte_count/1024/1024 != (wr_byte_count - fpga->wr.len)/1024/1024 ) { printf("."); fflush(stdout); } } // read result = fpga_read(fpga); if (result < 0) { fprintf(stderr, "SN %s FPGA #%d read error: %d (%s)\n", device->ztex_device->snString, num, result, libusb_strerror(result)); fpga->valid = 0; return result; } if (result > 0) { rd_byte_count += fpga->rd.read_limit; if (buf_check(fpga->rd.buf, fpga->rd.len, &fpga->data_in) < 0) { return -1; } partial_read_count += fpga->rd.partial_read_count; fpga->rd.partial_read_count = 0; } } // for( ;num_of_fpgas ;) return 1; }
static int warp_fpga_remove(struct platform_device *pdev) { struct warp_fpga *chip = warp_fpga_getdevice(); disable_irq(chip->irq); fpga_write(pdx->bar0, FPGA_CONFIG, fpga_read(pdx->bar0, FPGA_CONFIG) | TRIGGER_RECONFIG_FLAG ); udelay(100); fpga_write(pdx->bar0, FPGA_CONFIG, fpga_read(pdx->bar0, FPGA_CONFIG) & ~ TRIGGER_RECONFIG_FLAG ); ssleep(5); enable_irq(chip->irq); free_irq(chip->irq, chip); chip->sgl = NULL; return 0; }
/* Only call this if you are holding the fpga lock */ static int fpga_write_indirect_locked(void __iomem *fpga, int channel, int reg, __u8 value) { int val = (channel << 16) | (reg << 8) | value; if (fpga_wait_for_ciar(fpga)) return -ETIMEDOUT; fpga_write(fpga, BAR0_CIAR, val); return 0; }
void warp_fpga_enable_irq(int irq) { //imr_set(pdx, irq); unsigned imr = fpga_read(pdx->bar0, BAR0_IMR); // irq &= ~IMR_MASK; fpga_write(pdx->bar0, BAR0_IMR, imr | irq); pdx->imr |= irq; if (debug) printk("%s: irq: %x setting fpga imr to: %08x\n", __FUNCTION__, irq, imr | irq ); }
int write_silabs(PDEVICE_EXTENSION pdx, unsigned trunk, unsigned reg, unsigned data) { u32 val = (trunk << 16) | (reg << 8) | data; if (wait_for_ciar(pdx)) return -ETIMEDOUT; fpga_write(pdx->bar0, BAR0_CIAR, val); return 0; }
/* * Board specific gang-switched transceiver power on/off. * NOTE: OSK supplies power from DC, not battery. */ static int omap_ohci_transceiver_power(int on) { if (on) { if (machine_is_omap_innovator() && cpu_is_omap1510()) fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL) | ((1 << 5/*usb1*/) | (1 << 3/*usb2*/)), INNOVATOR_FPGA_CAM_USB_CONTROL); else if (machine_is_omap_osk()) tps65010_set_gpio_out_value(GPIO1, LOW); } else { if (machine_is_omap_innovator() && cpu_is_omap1510()) fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL) & ~((1 << 5/*usb1*/) | (1 << 3/*usb2*/)), INNOVATOR_FPGA_CAM_USB_CONTROL); else if (machine_is_omap_osk()) tps65010_set_gpio_out_value(GPIO1, HIGH); } return 0; }
/******************************************************************************* * Hlavni funkce *******************************************************************************/ int main(void) { short counter = 0; unsigned long a, b, c; initialize_hardware(); set_led_d6(1); //rozsvitit LED D6 set_led_d5(1); //rozsvitit LED D5 /**************************************************************************/ /* Aktualizovany hlavni program */ /**************************************************************************/ a = 0x12345678; b = 0x50000000; fpga_write(FPGA_ADDR_A, a); fpga_write(FPGA_ADDR_B, b); c = fpga_read(FPGA_ADDR_C); term_send_hex(a); term_send_str(" + "); term_send_hex(b); term_send_str(" = "); term_send_hex(c); term_send_crlf(); /**************************************************************************/ set_led_d5(0); //zhasnout LED D5 while (1) { delay_ms(1); //zpozdeni 1ms counter++; if (counter == 500) { flip_led_d6(); //invertovat LED counter = 0; } terminal_idle(); // obsluha terminalu } }
/* * Hardware specific transceiver power on/off */ static int omap_ohci_transceiver_power(int on) { if (on) { if (machine_is_omap_innovator() && cpu_is_omap1510()) fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL) | ((1 << 5/*usb1*/) | (1 << 3/*usb2*/)), INNOVATOR_FPGA_CAM_USB_CONTROL); else if (machine_is_omap_osk()) { /* FIXME: GPIO1 -> 1 on the TPS65010 I2C chip */ } } else { if (machine_is_omap_innovator() && cpu_is_omap1510()) fpga_write(fpga_read(INNOVATOR_FPGA_CAM_USB_CONTROL) & ~((1 << 5/*usb1*/) | (1 << 3/*usb2*/)), INNOVATOR_FPGA_CAM_USB_CONTROL); else if (machine_is_omap_osk()) { /* FIXME: GPIO1 -> 0 on the TPS65010 I2C chip */ } } return 0; }
static void __init innovator_init_smc91x(void) { if (cpu_is_omap1510()) { fpga_write(fpga_read(OMAP1510_FPGA_RST) & ~1, OMAP1510_FPGA_RST); udelay(750); } else { if (gpio_request(0, "SMC91x irq") < 0) { printk("Error requesting gpio 0 for smc91x irq\n"); return; } } }
int read_silabs(PDEVICE_EXTENSION pdx, unsigned trunk, unsigned reg, u8 *out) { u32 val = (trunk << 16) | (reg << 8) | (1 << 22); unsigned data; if (wait_for_ciar(pdx)) return -ETIMEDOUT; fpga_write(pdx->bar0, BAR0_CIAR, val); if (wait_for_ciar(pdx)) return -ETIMEDOUT; data = fpga_read(pdx->bar0, BAR0_CIAR); *out = data; return 0; }
void warp_fpga_reconfig(void) { struct warp_fpga *chip = warp_fpga_getdevice(); disable_irq(chip->irq); #ifndef WARP_V2 pci_save_state(chip->pdev); pci_disable_device(chip->pdev); #endif fpga_write(chip->fpga, FPGA_CONFIG, fpga_read(chip->fpga, FPGA_CONFIG) | TRIGGER_RECONFIG_FLAG ); udelay(100); fpga_write(chip->fpga, FPGA_CONFIG, fpga_read(chip->fpga, FPGA_CONFIG) & ~ TRIGGER_RECONFIG_FLAG ); ssleep(5); #ifndef WARP_V2 pci_restore_state(chip->pdev); pci_enable_device(chip->pdev); #endif enable_irq(chip->irq); }
static void __init innovator_init_smc91x(void) { if (cpu_is_omap1510()) { fpga_write(fpga_read(OMAP1510_FPGA_RST) & ~1, OMAP1510_FPGA_RST); udelay(750); } else { if ((omap_request_gpio(0)) < 0) { printk("Error requesting gpio 0 for smc91x irq\n"); return; } omap_set_gpio_edge_ctrl(0, OMAP_GPIO_RISING_EDGE); } }
int read_flash(PDEVICE_EXTENSION pdx, u8 *flash) { int i; if (wait_for_fiar(pdx)) return 1; /* failed */ /* Bank 1 read */ fpga_write(pdx->bar0, BAR0_FIAR, 0x00410000); for (i = 0; i < sizeof(FLASH_FIELDS_STRUCT); ++i, ++flash) { if (wait_for_fiar(pdx)) return 1; /* failed */ *flash = BAR0_READ_BYTE(pdx, BAR0_FIAR); } return 0; }
static void omap1510_audio_shutdown(void *dummy) { u8 fpga; printk(__FUNCTION__ "called\n"); #ifndef CONFIG_DSP_MCBSP1 // Disable the McBSP channel outw(0x0000, OMAP1510_MCBSP1_BASE + 0x806); // flush data outw(0x0000, OMAP1510_MCBSP1_BASE + 0x806); // flush data outw(0x0000, OMAP1510_MCBSP1_BASE + 0x80a); // disable SPCR1 outw(0x0000, OMAP1510_MCBSP1_BASE + 0x808); // disable SPCR2 #endif /* disable the audio clocks/signals */ l3_close(&uda1341); // Turn off clocks, but don't turn off audio amplifier // or you will hear a nasty noise when you turn it back // on. fpga = 0; fpga_write(fpga, OMAP1510P1_FPGA_AUDIO); }
static void omap1510_set_samplerate(long val) { struct uda1341_cfg cfg; u8 fpga; printk(__FUNCTION__ "called\n"); /* We don't want to mess with clocks when frames are in flight */ // TODO - could call omap1510_dma_flush_all, or could poll on // enable bit to wait for DMA writes to stop. /* wait for any frame to complete */ udelay(125); /* * We have the following clock sources: * 12.288 MHz and 16.9344 MHz. * We have dividers in the FPGA (1, 2, 4), and in * the codec. * clock epld div codec_div freq * 12.288 1 256 48K * " 4 384 8K * 16.9344 1 384 44.1K * " 2 384 22.05K * " 4 384 11.025K */ if (val >= 48000) val = 48000; else if (val >= 44100) val = 44100; else if (val >= 22050) val = 22050; else if (val >= 11025) val = 11025; else val = 8000; /* Set the external clock generator */ switch (val) { case 48000: case 8000: /* 12.288 MHz */ fpga = fpga_read(OMAP1510P1_FPGA_AUDIO); if (fpga & 0x4) { fpga &= ~0x4; fpga_write(fpga, OMAP1510P1_FPGA_AUDIO); } break; default: /* 16.3944 MHz */ fpga = fpga_read(OMAP1510P1_FPGA_AUDIO); if ((fpga & 0x4) == 0) { fpga |= 0x4; fpga_write(fpga, OMAP1510P1_FPGA_AUDIO); } break; } /* Select the clock divisor */ switch (val) { #if 0 case case cfg.fs = 512; break; #endif case 48000: cfg.fs = 256; break; default: cfg.fs = 384; break; } cfg.format = FMT_I2S; l3_command(&uda1341, L3_UDA1341_CONFIGURE, &cfg); audio_samplerate = val; }
/* * Note that on Innovator-1510 UART2 pins conflict with USB2. * By default UART2 does not work on Innovator-1510 if you have * USB OHCI enabled. To use UART2, you must disable USB2 first. */ void __init omap_serial_init(void) { int i; const struct omap_uart_config *info; if (cpu_is_omap730()) { serial_platform_data[0].regshift = 0; serial_platform_data[1].regshift = 0; serial_platform_data[0].irq = INT_730_UART_MODEM_1; serial_platform_data[1].irq = INT_730_UART_MODEM_IRDA_2; } if (cpu_is_omap1510()) { serial_platform_data[0].uartclk = OMAP1510_BASE_BAUD * 16; serial_platform_data[1].uartclk = OMAP1510_BASE_BAUD * 16; serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16; } info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config); if (info == NULL) return; for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { unsigned char reg; if (!((1 << i) & info->enabled_uarts)) { serial_platform_data[i].membase = NULL; serial_platform_data[i].mapbase = 0; continue; } switch (i) { case 0: uart1_ck = clk_get(NULL, "uart1_ck"); if (IS_ERR(uart1_ck)) printk("Could not get uart1_ck\n"); else { clk_use(uart1_ck); if (cpu_is_omap1510()) clk_set_rate(uart1_ck, 12000000); } if (cpu_is_omap1510()) { omap_cfg_reg(UART1_TX); omap_cfg_reg(UART1_RTS); if (machine_is_omap_innovator()) { reg = fpga_read(OMAP1510_FPGA_POWER); reg |= OMAP1510_FPGA_PCR_COM1_EN; fpga_write(reg, OMAP1510_FPGA_POWER); udelay(10); } } break; case 1: uart2_ck = clk_get(NULL, "uart2_ck"); if (IS_ERR(uart2_ck)) printk("Could not get uart2_ck\n"); else { clk_use(uart2_ck); if (cpu_is_omap1510()) clk_set_rate(uart2_ck, 12000000); else clk_set_rate(uart2_ck, 48000000); } if (cpu_is_omap1510()) { omap_cfg_reg(UART2_TX); omap_cfg_reg(UART2_RTS); if (machine_is_omap_innovator()) { reg = fpga_read(OMAP1510_FPGA_POWER); reg |= OMAP1510_FPGA_PCR_COM2_EN; fpga_write(reg, OMAP1510_FPGA_POWER); udelay(10); } } break; case 2: uart3_ck = clk_get(NULL, "uart3_ck"); if (IS_ERR(uart3_ck)) printk("Could not get uart3_ck\n"); else { clk_use(uart3_ck); if (cpu_is_omap1510()) clk_set_rate(uart3_ck, 12000000); } if (cpu_is_omap1510()) { omap_cfg_reg(UART3_TX); omap_cfg_reg(UART3_RX); } break; } omap_serial_reset(&serial_platform_data[i]); } }
static int warp_fpga_probe(struct pci_dev *pdev, const struct pci_device_id *id) { s32 ret = 0; struct warp_fpga *chip = NULL; int tries; chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; chip->dev = &pdev->dev; chip->pdev = pdev; ret = pci_enable_device(pdev); if (ret) { dev_err(&pdev->dev, "%s : pci_enable_device FAILED", __func__); goto err_pci_enable; } // Set the PCI Master Bit to true always in the PCI bridge pci_set_master(pdev); dev_dbg(&pdev->dev, "try set_consistent_dma_mask(32)\n"); ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (ret) { dev_err(&pdev->dev, "set_dma_mask(32) failed\n"); goto err_set_dma_mask; } ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); if (ret) { dev_err(&pdev->dev, "set_consistent_dma_mask(32) failed\n"); goto err_set_dma_mask; } ret = pci_request_regions(pdev, KBUILD_MODNAME); if (ret) { dev_err(&pdev->dev, "pci_request_regions FAILED-%d", ret); goto err_request_regions; } chip->base = pci_iomap(pdev, 0, 0); if (chip->base == 0) { dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__); ret = -ENOMEM; goto err_iomap; } pci_set_drvdata(pdev, chip); mutex_init(&chip->lock); // Setup the IRQ chip->irq = pdev->irq; chip->fpga = chip->base; // Int the old pdx struct to be compatiable with the read of function pdx->info.irql = chip->irq; pdx->bar0 = chip->base; pdx->pdev = pdev; // Verify current FPGA mode of operation for (tries = 0; tries < 2; tries++) { if ((fpga_read(chip->base, BAR0_FPGA_UPDATE) & 0x300) == 0x0) { dev_err(&pdev->dev, "Detected FPGA in Factory mode\n"); // Detected Factory Mode, try to restart the pci_bus warp_fpga_reconfig(); if ((fpga_read(chip->base, BAR0_FPGA_UPDATE) & 0x300) == 0x100) { dev_info(&pdev->dev, "FPGA restored mode to operational\n"); break; } continue; } break; } // Initialize the procfs interface taco_proc_init(pdx); // Init the dma buffer and scatter list ret = dma_init_module(chip); if (ret != 0) { dev_err(&pdev->dev, "dma_init_module FAILED-%d", ret); goto err_taco; } if (warpfpgactrl_init(chip) != 0 ) { dev_err(&pdev->dev, "warpfpgactrl_init FAILED"); goto err_taco; } // Only reset the silabs once if (daytona_silabs_reset(pdx)) { printk(KERN_ERR "Unable to reset silabs\n"); goto err_taco; } printk("Base FPGA Address: %p = %p\n", chip->fpga, chip->base); // Set the device g_warp_fpga_dev = pdev; warpfpga_active = 1; // Place DSP in Bypass mode if DSP count is zero if (warp_fpga_dsp_count() == 0) { printk("Placing the FPGA in DSP Bypass Mode since no DSP found\n"); u32 val = fpga_read(chip->base, BAR0_DIAG) | 0x800; fpga_write(chip->base, BAR0_DIAG,val); } return ret; err_taco: taco_proc_remove(); err_iomap: pci_release_regions(pdev); err_set_dma_mask: err_request_regions: pci_disable_device(pdev); err_pci_enable: kfree(chip); dev_err(&pdev->dev, "%s Failed returns %d\n", __func__, ret); return ret; }
void fpga_wr1 (uint8_t addr_hi, uint8_t addr_lo, uint8_t data) { fpga_write (addr_hi, addr_lo, &data, 1); }
static void innovator1510_panel_disable(struct lcd_panel *panel) { fpga_write(0x0, OMAP1510_FPGA_LCD_PANEL_CONTROL); }
static int innovator1510_panel_enable(struct lcd_panel *panel) { fpga_write(0x7, OMAP1510_FPGA_LCD_PANEL_CONTROL); return 0; }
static int warp_fpga_probe(struct platform_device *pdev) { struct warp_fpga *chip = NULL; struct device_node *np; int tries, ret = 0; struct resource res; // Create the Warp FPGA structure printk(KERN_INFO "Allocating FPGA structure\n"); chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; chip->pdev = pdev; chip->dev = &pdev->dev; // Extract all FPGA parameters from open firmware np = of_find_compatible_node(NULL, NULL, "pika,fpga"); if (np == NULL) { dev_err(&pdev->dev, "%s of_find_compatible_node FAILED\n", __func__); goto error_cleanup; } // Check resource if (of_address_to_resource(np, 0, &res)) { dev_err(&pdev->dev, "%s of_address_to_resource FAILED\n", __func__); goto error_cleanup; } printk(KERN_INFO "pika,fpga resource => %x-%x\n", res.start, res.end); // Map FPGA base chip->base = chip->fpga = ioremap(res.start, 0x2200); if (chip->fpga == NULL) { dev_err(&pdev->dev, "%s ioremap FAILED\n", __func__); goto error_cleanup; } // Setup the IRQ chip->irq = irq_of_parse_and_map(np, 0); if (chip->irq == NO_IRQ) { dev_err(&pdev->dev, "%s irq_of_parse_and_map FAILED\n", __func__); goto error_cleanup; } // Done with np of_node_put(np); // Extract all FPGA-SGL parameters from open firmware np = of_find_compatible_node(NULL, NULL, "pika,fpga-sgl"); // Map FPGA-SGL base chip->sgl = of_iomap(np, 0); if (chip->sgl == NULL) { dev_err(&pdev->dev, "%s of_iomap FAILED\n", __func__); goto error_cleanup; } // Done with np of_node_put(np); // Mutex creation mutex_init(&chip->lock); // Backup platform device in driver data platform_set_drvdata(pdev, chip); // Int the old pdx struct to be compatiable with the read of function pdx->info.irql = chip->irq; pdx->pdev = chip->pdev; pdx->bar0 = chip->fpga; printk(KERN_INFO "PDX OK (irq:%d) (bar0:%p)\n", pdx->info.irql, pdx->bar0); // Verify current FPGA mode of operation for (tries = 0; tries < 3; tries++) { if ((fpga_read(chip->base, BAR0_FPGA_UPDATE) & 0x300) == 0x0) { dev_err(&pdev->dev, "Detected FPGA in Factory mode\n"); // Detected Factory Mode, try to restart the ? warp_fpga_reconfig(); if ((fpga_read(chip->base, BAR0_FPGA_UPDATE) & 0x300) == 0x100) { dev_info(&pdev->dev, "FPGA restored mode to operational\n"); break; } continue; } break; } // Initialize the procfs interface taco_proc_init(pdx); // Init the DMA buffers and scatter-gather list ret = dma_init_module(chip); if (ret != 0) { dev_err(&pdev->dev, "dma_init_module FAILED-%d", ret); goto err_taco; } if (warpfpgactrl_init() != 0) { dev_err(&pdev->dev, "warpfpgactrl_init FAILED"); goto err_taco; } // Only reset the silabs once /* if (daytona_silabs_reset(pdx)) { printk(KERN_ERR "Unable to reset silabs\n"); goto err_taco; } */ printk("Base FPGA Address: %p = %p\n", chip->fpga, chip->base); // Set the device g_warp_fpga_dev = pdev; warpfpga_active = 1; #ifndef WARP_V2 // Place DSP in Bypass mode if DSP count is zero if (warp_fpga_dsp_count() == 0) { printk("Placing the FPGA in DSP Bypass Mode since no DSP found\n"); u32 val = fpga_read(chip->base, FPGA_DIAG) | 0x800; fpga_write(chip->base, FPGA_DIAG, val); } #endif return ret; err_taco: taco_proc_remove(); error_cleanup: if (np) of_node_put(np); if (chip->fpga) iounmap(chip->fpga); if (chip->sgl) iounmap(chip->sgl); kfree(chip); dev_err(&pdev->dev, "%s Failed returns %d\n", __func__, ret); return ret; }
static void omap1510_audio_init(void *dummy) { dma_regs_t *dma_regs = output_stream.dma_regs; u8 fpga; printk(__FUNCTION__ "called\n"); /* Init FPGA. Turn on Audio amplifier and set 12.288 MHz clock */ fpga = fpga_read(OMAP1510P1_FPGA_POWER); fpga &= 0xfe; fpga_write(fpga, OMAP1510P1_FPGA_POWER); fpga = 0xc; fpga_write(fpga, OMAP1510P1_FPGA_AUDIO); #ifndef CONFIG_DSP_MCBSP1 /* Now here's an ugly hack. To use McBSP1, you need to enable a clock on the DSP. So enable the MPUI, set the clock, and start the DSP. An even uglier, evil hack. If this is going to take the DSP out of reset, shove an idle loop at the reset vector and make it loop instead of crash. You will still see a DSP watchdog timer go off. */ { u16 tmp; u8 c55_start[] = { 0x7A, 0x00, 0x00, 0x0C, 0x4A, 0x7A, 0x20, 0x20, 0x20, 0x20 }; tmp = inw(ARM_RSTCT1); // check if DSP is up if (!(tmp & (ARM_RSTCT1_DSP_RST|ARM_RSTCT1_DSP_EN))) { if (!(tmp & ARM_RSTCT1_DSP_RST)) { // MPUI in reset tmp |= ARM_RSTCT1_DSP_RST; outw(tmp, ARM_RSTCT1); ck_enable(api_ck); } // REVISIT: I'm not finding this in the OMAP1509 TRM: tmp = inw(0xe1008008); if (0 == (tmp & 0x2)) { // DSP CLKM enable tmp |= 0x2; outw(tmp, 0xe1008008); } tmp = inw(0xe1008014); if (0 == (tmp & 0x1)) { // DSP PER_EN bit tmp |= 0x1; outw(tmp, 0xe1008014); } tmp = inw(ARM_CKCTL); // Enable DSP tmp |= 0x2000; outw(tmp, ARM_CKCTL); // Write C55 code at reset vector. memcpy((OMAP_DSP_BASE + 0x4c000), &c55_start, sizeof(c55_start)); outw(0x5, MPUI_DSP_BOOT_CONFIG); // Set DSP boot mode tmp = inw(ARM_RSTCT1); // take DSP out of reset tmp |= ARM_RSTCT1_DSP_RST|ARM_RSTCT1_DSP_EN; outw(tmp, ARM_RSTCT1); } else { // DSP's up, just check the clock/per bits tmp = inw(0xe1008008); if (0 == (tmp & 0x2)) { // DSP CLKM enable tmp |= 0x2; outw(tmp, 0xe1008008); } tmp = inw(0xe1008014); if (0 == (tmp & 0x1)) { // DSP PER_EN bit tmp |= 0x1; outw(tmp, 0xe1008014); } } } /* While we're waiting for the UDA1341 to wake up, let's configure the DMA channel and MCBSP. */ // Setup DMA channel to McBSP1 audio Tx. dma_regs->csdp = 0x0a01; dma_regs->ccr = 0x1000 | audio_state.output_dma; // source auto increment, don't enable yet dma_regs->cicr = 0x0b; dma_regs->cdsa_l = ((OMAP1510_MCBSP1_BASE + 0x806) & 0xffff); //McBSP1 DXR1 dma_regs->cdsa_u = ((OMAP1510_MCBSP1_BASE + 0x806) >> 16); dma_regs->cfn = 0x1; omap_dma_setup(audio_state.output_dma, eDmaOut); // Initialize McBSP channel outw(0x0000, OMAP1510_MCBSP1_BASE + 0x80a); // SPCR1 outw(0x0000, OMAP1510_MCBSP1_BASE + 0x808); // SPCR2 outw(0x0f03, OMAP1510_MCBSP1_BASE + 0x824); // PCR0 outw(0x0040, OMAP1510_MCBSP1_BASE + 0x80e); // RCR1 outw(0x8045, OMAP1510_MCBSP1_BASE + 0x80c); // RCR2 outw(0x0040, OMAP1510_MCBSP1_BASE + 0x812); // XCR1 outw(0x8041, OMAP1510_MCBSP1_BASE + 0x810); // XCR2 outw(0x0f0b, OMAP1510_MCBSP1_BASE + 0x816); // SRGR1 outw(0x101f, OMAP1510_MCBSP1_BASE + 0x814); // SRGR2 outw(0x0001, OMAP1510_MCBSP1_BASE + 0x80a); // SPCR1 enable outw(0x03f1, OMAP1510_MCBSP1_BASE + 0x808); // SPCR2 enable #endif /* Wait for the UDA1341 to wake up */ mdelay(1); /* external clock configuration */ omap1510_set_samplerate(audio_samplerate); /* Initialize the UDA1341 internal state */ l3_open(&uda1341); }