Date: Mon, 28 Jan 2013 15:20:37 -0800 From: Oleksandr Tymoshenko <gonzo@bluezbox.com> To: George Mitchell <george@m5p.com> Cc: freebsd-arm@freebsd.org Subject: Re: Thanks for the Raspberry Pi! Message-ID: <510707C5.1020905@bluezbox.com> In-Reply-To: <51065DB9.4090406@m5p.com> References: <51065DB9.4090406@m5p.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On 1/28/2013 3:15 AM, George Mitchell wrote: > Today is my birthday, and the best present I have is that my Raspberry > Pi is running FreeBSD plus CUPS and acting as a print server for the > FreeBSD machines (and one Windoze machine) on my home network. My > sincere thanks go to everybody who helped bring FreeBSD to the ARM and > specifically to the Pi. It would be awesome if we could get ARM > promoted to Tier 1 support this year Happy birthday. George! :) > I'm interested in working on a driver for the pulse-width modulation > audio output on the Pi, and I have the Broadcom document describing how > it works. What are the chances I could base such a driver on some > existing FreeBSD audio driver? I do not think there is PWM-based audio driver. I was trying to implement VCHIQ-based audio driver[1] but ran into some locking issues with VCHIQ driver and put the project on hold. You can use it as a skeleton for your audio driver though. Also as far as I can see from spec PWM utilizes DMA so you might want to give a try this driver[2]. It's reworked version of Daisuke Aoyama's patch. Usage pattern would be something like code below. In real driver you'd want to use bus_dma operations though, not direct calls to cache ops. [1] http://people.freebsd.org/~gonzo/arm/rpi/vchiq_audio.tar.gz [2] http://people.freebsd.org/~gonzo/arm/patches/rpi_dma.diff int dma_started = 0; int dma_set = 0; int dma = 0; void *page1 = NULL; void *page2 = NULL; vm_paddr_t pa1; vm_paddr_t pa2; static uint8_t pattern = 0xa5; static void dma_intr(int ch, void *arg) { uint32_t *p1, *p2; printf("dma_intr: %d, %p\n", ch, arg); cpu_dcache_inv_range((vm_offset_t)page2, PAGE_SIZE); cpu_l2cache_inv_range((vm_offset_t)page2, PAGE_SIZE); p1 = (void*)page1; p2 = (void*)page2; printf("%08x vs %08x\n", *p1, *p2); for (int i = 0; i < PAGE_SIZE/4; i++) { if (p1[i] != p2[i]) { printf("diff at %d\n", i); break; } } dma_started = 0; } static int start_dma_test() { return (0); if (!dma_set) { printf("Setting DMA\n"); dma_set = 1; page1 = contigmalloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT, 0ul, 0xfffffffful, PAGE_SIZE, 0); page2 = contigmalloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT, 0ul, 0xfffffffful, PAGE_SIZE, 0); pa1 = vtophys(page1); pa2 = vtophys(page2); printf("page1 = %p -> %p\n", page1, (void*)pa1); printf("page2 = %p -> %p\n", page2, (void*)pa1); dma = bcm_dma_allocate(BCM_DMA_CH_ANY); printf("Allocated channel: %d\n", dma); bcm_dma_setup_intr(dma, dma_intr, NULL); bcm_dma_setup_src(dma, 0, 1); bcm_dma_setup_dst(dma, 0, 1); } if (!dma_started) { memset(page1, pattern, PAGE_SIZE); memset(page2, 0x00, PAGE_SIZE); pattern++; cpu_dcache_wbinv_range((vm_offset_t)page1, PAGE_SIZE); cpu_l2cache_wbinv_range((vm_offset_t)page1, PAGE_SIZE); cpu_dcache_wbinv_range((vm_offset_t)page2, PAGE_SIZE); cpu_l2cache_wbinv_range((vm_offset_t)page2, PAGE_SIZE); printf("DMA started!\n"); bcm_dma_start(dma, pa1, pa2, PAGE_SIZE); } dma_started = 1; return (0); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?510707C5.1020905>