Index: arm/broadcom/bcm2835/bcm2835_audio.c =================================================================== --- arm/broadcom/bcm2835/bcm2835_audio.c (revision 328501) +++ arm/broadcom/bcm2835/bcm2835_audio.c (working copy) @@ -66,7 +66,7 @@ #define AUDIO_STOP (1 << 2) #define VCHIQ_AUDIO_PACKET_SIZE 4000 -#define VCHIQ_AUDIO_BUFFER_SIZE 10*VCHIQ_AUDIO_PACKET_SIZE +#define VCHIQ_AUDIO_BUFFER_SIZE 4*VCHIQ_AUDIO_PACKET_SIZE #define VCHIQ_AUDIO_MAX_VOLUME /* volume in terms of 0.01dB */ @@ -210,16 +210,21 @@ if (m.type == VC_AUDIO_MSG_TYPE_RESULT) { if (m.u.result.success) { device_printf(sc->dev, - "msg type %08x failed\n", - m.type); + "msg type %08x failed: %d\n", + m.type, m.u.result.success); } } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) { - struct bcm2835_audio_chinfo *ch = m.u.complete.cookie; + struct bcm2835_audio_chinfo *ch = &sc->pch; + // printf("complete sc=%p ch=%p\n", sc, ch); int count = m.u.complete.count & 0xffff; int perr = (m.u.complete.count & (1U << 30)) != 0; + // static int xxxcnt; + // printf("[%08d] VC_AUDIO_MSG_TYPE_COMPLETE status=%d, count=%d, perr=%d\n", xxxcnt++, status, count, perr); ch->callbacks++; if (perr) + printf("UNDERRUN\n"); + if (perr) ch->underruns++; BCM2835_AUDIO_LOCK(sc); @@ -237,12 +242,14 @@ device_printf(sc->dev, "available_space == %d, count = %d, perr=%d\n", ch->available_space, count, perr); device_printf(sc->dev, - "retrieved_samples = %lld, submitted_samples = %lld\n", - ch->retrieved_samples, ch->submitted_samples); + "retrieved_samples = %ju, submitted_samples = %ju\n", + (uintmax_t)ch->retrieved_samples, (uintmax_t)ch->submitted_samples); } ch->available_space += count; ch->retrieved_samples += count; } + else + printf("PERR with count=%d\n", count); if (perr || (ch->available_space >= VCHIQ_AUDIO_PACKET_SIZE)) cv_signal(&sc->worker_cv); } @@ -286,8 +293,10 @@ status = vchi_service_open(sc->vchi_instance, ¶ms, &sc->vchi_handle); - if (status != 0) + if (status != 0) { + printf("vchi_service_open failed: %d\n", status); sc->vchi_handle = VCHIQ_SERVICE_HANDLE_INVALID; + } } static void @@ -445,8 +454,8 @@ m.type = VC_AUDIO_MSG_TYPE_WRITE; m.u.write.count = count; m.u.write.max_packet = VCHIQ_AUDIO_PACKET_SIZE; - m.u.write.callback = NULL; - m.u.write.cookie = ch; + m.u.write.cookie1 = 0; + m.u.write.cookie2 = 0; m.u.write.silence = 0; ret = vchi_msg_queue(sc->vchi_handle, @@ -687,6 +696,9 @@ case PCMTRIG_STOP: case PCMTRIG_ABORT: + printf("submitted_samples = %lu\n", ch->submitted_samples); + printf("retrieved_samples = %lu\n", ch->retrieved_samples); + printf("available_space = %d\n", ch->available_space); bcm2835_worker_play_stop(sc); break; Index: arm/broadcom/bcm2835/bcm2835_gpio.c =================================================================== --- arm/broadcom/bcm2835/bcm2835_gpio.c (revision 328501) +++ arm/broadcom/bcm2835/bcm2835_gpio.c (working copy) @@ -48,6 +48,7 @@ #include #include +#include #include #include @@ -793,6 +794,9 @@ if (sc->sc_busdev == NULL) goto fail; + fdt_pinctrl_register(dev, "brcm,pins"); + fdt_pinctrl_configure_tree(dev); + return (0); fail: @@ -1187,6 +1191,55 @@ return (ofw_bus_get_node(bus)); } +static int +bcm_gpio_configure_pins(device_t dev, phandle_t cfgxref) +{ + phandle_t cfgnode; + int i, pintuples, pulltuples; + uint32_t pin; + uint32_t *pins; + uint32_t *pulls; + uint32_t function; + static struct ti_pinmux_softc *sc; + + sc = device_get_softc(dev); + cfgnode = OF_node_from_xref(cfgxref); + + pintuples = OF_getencprop_alloc(cfgnode, "brcm,pins", sizeof(*pins), + (void **)&pins); + + if (pintuples < 0) + return (ENOENT); + + if (pintuples == 0) + return (0); /* Empty property is not an error. */ + + if (OF_getencprop(cfgnode, "brcm,function", &function, + sizeof(function)) <= 0) + return (EINVAL); + + + pulls = NULL; + pulltuples = OF_getencprop_alloc(cfgnode, "brcm,pull", sizeof(*pulls), + (void **)&pulls); + + if ((pulls != NULL) && (pulltuples != pintuples)) { + OF_prop_free(pins); + OF_prop_free(pulls); + return (EINVAL); + } + + for (i = 0; i < pintuples; i++) { + pin = pins[i]; + } + + OF_prop_free(pins); + if (pulls) + OF_prop_free(pulls); + + return (0); +} + static device_method_t bcm_gpio_methods[] = { /* Device interface */ DEVMETHOD(device_probe, bcm_gpio_probe), @@ -1217,6 +1270,9 @@ /* ofw_bus interface */ DEVMETHOD(ofw_bus_get_node, bcm_gpio_get_node), + /* fdt_pinctrl interface */ + DEVMETHOD(fdt_pinctrl_configure, bcm_gpio_configure_pins), + DEVMETHOD_END }; Index: arm/broadcom/bcm2835/vc_vchi_audioserv_defs.h =================================================================== --- arm/broadcom/bcm2835/vc_vchi_audioserv_defs.h (revision 328501) +++ arm/broadcom/bcm2835/vc_vchi_audioserv_defs.h (working copy) @@ -114,8 +114,8 @@ typedef struct { uint32_t count; /* in bytes */ - void *callback; - void *cookie; + uint32_t cookie1; + uint32_t cookie2; uint16_t silence; uint16_t max_packet; } VC_AUDIO_WRITE_T; @@ -131,8 +131,8 @@ typedef struct { int32_t count; /* Success value */ - void *callback; - void *cookie; + uint32_t cookie1; + uint32_t cookie2; } VC_AUDIO_COMPLETE_T; /* Message header for all messages in HOST->VC direction */ Index: arm64/conf/GENERIC =================================================================== --- arm64/conf/GENERIC (revision 328501) +++ arm64/conf/GENERIC (working copy) @@ -250,3 +250,6 @@ # The crypto framework is required by IPSEC device crypto # Required by IPSEC + +device vchiq # Required by IPSEC +device sound Index: contrib/vchiq/interface/compat/vchi_bsd.h =================================================================== --- contrib/vchiq/interface/compat/vchi_bsd.h (revision 328501) +++ contrib/vchiq/interface/compat/vchi_bsd.h (working copy) @@ -432,6 +432,12 @@ #define smp_rmb rmb #define smp_wmb wmb +#if defined(__aarch64__) +#define DSB() dsb(sy) +#else +#define DSB() dsb() +#endif + #define device_print_prettyname(dev) device_printf((dev), "") #endif /* __VCHI_BSD_H__ */ Index: contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c =================================================================== --- contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c (revision 328501) +++ contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c (working copy) @@ -137,6 +137,7 @@ int err; int i; + printf("vchi: g_cache_line_size = %d\n", g_cache_line_size); /* Allocate space for the channels in coherent memory */ g_slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); g_fragment_size = 2*g_cache_line_size; @@ -204,7 +205,7 @@ bcm_mbox_write(BCM2835_MBOX_CHAN_VCHIQ, (unsigned int)g_slot_phys); vchiq_log_info(vchiq_arm_log_level, - "vchiq_init - done (slots %x, phys %x)", + "vchiq_init - done (slots %x, phys %jx)", (unsigned int)vchiq_slot_zero, g_slot_phys); vchiq_call_connected_callbacks(); @@ -402,7 +403,7 @@ { PAGELIST_T *pagelist; vm_page_t* pages; - unsigned long *addrs; + uint32_t *addrs; unsigned int num_pages, i; vm_offset_t offset; int pagelist_size; @@ -456,7 +457,7 @@ } vchiq_log_trace(vchiq_arm_log_level, - "create_pagelist - %x (%d bytes @%p)", (unsigned int)pagelist, count, buf); + "create_pagelist - %pK", pagelist); if (!pagelist) return -ENOMEM; @@ -533,8 +534,9 @@ (fragments - g_fragments_base)/g_fragment_size; } - pa = pmap_extract(PCPU_GET(curpmap), (vm_offset_t)buf); - dcache_wbinv_poc((vm_offset_t)buf, pa, count); +#ifdef __aarch64__ + cpu_dcache_wbinv_range((vm_offset_t)buf, count); +#endif bus_dmamap_sync(bi->pagelist_dma_tag, bi->pagelist_dma_map, BUS_DMASYNC_PREWRITE); @@ -560,7 +562,7 @@ pagelist = bi->pagelist; vchiq_log_trace(vchiq_arm_log_level, - "free_pagelist - %x, %d (%lu bytes @%p)", (unsigned int)pagelist, actual, pagelist->length, bi->buf); + "free_pagelist - %x, %d (%u bytes @%p)", (unsigned int)pagelist, actual, pagelist->length, bi->buf); num_pages = (pagelist->length + pagelist->offset + PAGE_SIZE - 1) / Index: contrib/vchiq/interface/vchiq_arm/vchiq_core.c =================================================================== --- contrib/vchiq/interface/vchiq_arm/vchiq_core.c (revision 328501) +++ contrib/vchiq/interface/vchiq_arm/vchiq_core.c (working copy) @@ -418,12 +418,13 @@ } static inline void -remote_event_create(REMOTE_EVENT_T *event) +remote_event_create(VCHIQ_STATE_T *state, REMOTE_EVENT_T *event) { + struct semaphore *sema = (struct semaphore *)((char *)state + event->event); event->armed = 0; /* Don't clear the 'fired' flag because it may already have been set ** by the other side. */ - _sema_init(event->event, 0); + _sema_init(sema, 0); } __unused static inline void @@ -433,13 +434,14 @@ } static inline int -remote_event_wait(REMOTE_EVENT_T *event) +remote_event_wait(VCHIQ_STATE_T *state, REMOTE_EVENT_T *event) { + struct semaphore *sema = (struct semaphore *)((char *)state + event->event); if (!event->fired) { event->armed = 1; - dsb(); + DSB(); if (!event->fired) { - if (down_interruptible(event->event) != 0) { + if (down_interruptible(sema) != 0) { event->armed = 0; return 0; } @@ -453,26 +455,26 @@ } static inline void -remote_event_signal_local(REMOTE_EVENT_T *event) +remote_event_signal_local(VCHIQ_STATE_T *state, REMOTE_EVENT_T *event) { event->armed = 0; - up(event->event); + up((struct semaphore *)((char *)state + event->event)); } static inline void -remote_event_poll(REMOTE_EVENT_T *event) +remote_event_poll(VCHIQ_STATE_T *state, REMOTE_EVENT_T *event) { if (event->fired && event->armed) - remote_event_signal_local(event); + remote_event_signal_local(state, event); } void remote_event_pollall(VCHIQ_STATE_T *state) { - remote_event_poll(&state->local->sync_trigger); - remote_event_poll(&state->local->sync_release); - remote_event_poll(&state->local->trigger); - remote_event_poll(&state->local->recycle); + remote_event_poll(state, &state->local->sync_trigger); + remote_event_poll(state, &state->local->sync_release); + remote_event_poll(state, &state->local->trigger); + remote_event_poll(state, &state->local->recycle); } /* Round up message sizes so that any space at the end of a slot is always big @@ -553,7 +555,7 @@ wmb(); /* ... and ensure the slot handler runs. */ - remote_event_signal_local(&state->local->trigger); + remote_event_signal_local(state, &state->local->trigger); } /* Called from queue_message, by the slot handler and application threads, @@ -1017,7 +1019,7 @@ (lmutex_lock_interruptible(&state->sync_mutex) != 0)) return VCHIQ_RETRY; - remote_event_wait(&local->sync_release); + remote_event_wait(state, &local->sync_release); rmb(); @@ -1849,17 +1851,17 @@ bulk = &queue->bulks[ BULK_INDEX(queue->remote_insert)]; bulk->remote_data = - (void *)((int *)header->data)[0]; + (void *)(long)((int *)header->data)[0]; bulk->remote_size = ((int *)header->data)[1]; wmb(); vchiq_log_info(vchiq_core_log_level, - "%d: prs %s@%x (%d->%d) %x@%x", + "%d: prs %s@%pK (%d->%d) %x@%pK", state->id, msg_type_str(type), - (unsigned int)header, + header, remoteport, localport, bulk->remote_size, - (unsigned int)bulk->remote_data); + bulk->remote_data); queue->remote_insert++; @@ -2051,7 +2053,7 @@ while (1) { DEBUG_COUNT(SLOT_HANDLER_COUNT); DEBUG_TRACE(SLOT_HANDLER_LINE); - remote_event_wait(&local->trigger); + remote_event_wait(state, &local->trigger); rmb(); @@ -2141,7 +2143,7 @@ VCHIQ_SHARED_STATE_T *local = state->local; while (1) { - remote_event_wait(&local->recycle); + remote_event_wait(state, &local->recycle); process_free_queue(state); } @@ -2165,7 +2167,7 @@ int type; unsigned int localport, remoteport; - remote_event_wait(&local->sync_trigger); + remote_event_wait(state, &local->sync_trigger); rmb(); @@ -2478,24 +2480,24 @@ state->data_use_count = 0; state->data_quota = state->slot_queue_available - 1; - local->trigger.event = &state->trigger_event; - remote_event_create(&local->trigger); + local->trigger.event = offsetof(VCHIQ_STATE_T, trigger_event); + remote_event_create(state, &local->trigger); local->tx_pos = 0; - local->recycle.event = &state->recycle_event; - remote_event_create(&local->recycle); + local->recycle.event = offsetof(VCHIQ_STATE_T, recycle_event); + remote_event_create(state, &local->recycle); local->slot_queue_recycle = state->slot_queue_available; - local->sync_trigger.event = &state->sync_trigger_event; - remote_event_create(&local->sync_trigger); + local->sync_trigger.event = offsetof(VCHIQ_STATE_T, sync_trigger_event); + remote_event_create(state, &local->sync_trigger); - local->sync_release.event = &state->sync_release_event; - remote_event_create(&local->sync_release); + local->sync_release.event = offsetof(VCHIQ_STATE_T, sync_release_event); + remote_event_create(state, &local->sync_release); /* At start-of-day, the slot is empty and available */ ((VCHIQ_HEADER_T *)SLOT_DATA_FROM_INDEX(state, local->slot_sync))->msgid = VCHIQ_MSGID_PADDING; - remote_event_signal_local(&local->sync_release); + remote_event_signal_local(state, &local->sync_release); local->debug[DEBUG_ENTRIES] = DEBUG_MAX; @@ -3817,8 +3819,8 @@ vchiq_dump(dump_context, buf, len + 1); len = snprintf(buf, sizeof(buf), - " Ctrl: tx_count=%d, tx_bytes=%llu, " - "rx_count=%d, rx_bytes=%llu", + " Ctrl: tx_count=%d, tx_bytes=%ju, " + "rx_count=%d, rx_bytes=%ju", service->stats.ctrl_tx_count, service->stats.ctrl_tx_bytes, service->stats.ctrl_rx_count, @@ -3826,8 +3828,8 @@ vchiq_dump(dump_context, buf, len + 1); len = snprintf(buf, sizeof(buf), - " Bulk: tx_count=%d, tx_bytes=%llu, " - "rx_count=%d, rx_bytes=%llu", + " Bulk: tx_count=%d, tx_bytes=%ju, " + "rx_count=%d, rx_bytes=%ju", service->stats.bulk_tx_count, service->stats.bulk_tx_bytes, service->stats.bulk_rx_count, Index: contrib/vchiq/interface/vchiq_arm/vchiq_core.h =================================================================== --- contrib/vchiq/interface/vchiq_arm/vchiq_core.h (revision 328501) +++ contrib/vchiq/interface/vchiq_arm/vchiq_core.h (working copy) @@ -185,11 +185,11 @@ #define DEBUG_INITIALISE(local) int *debug_ptr = (local)->debug; #define DEBUG_TRACE(d) \ - do { debug_ptr[DEBUG_ ## d] = __LINE__; dsb(); } while (0) + do { debug_ptr[DEBUG_ ## d] = __LINE__; DSB(); } while (0) #define DEBUG_VALUE(d, v) \ - do { debug_ptr[DEBUG_ ## d] = (v); dsb(); } while (0) + do { debug_ptr[DEBUG_ ## d] = (v); DSB(); } while (0) #define DEBUG_COUNT(d) \ - do { debug_ptr[DEBUG_ ## d]++; dsb(); } while (0) + do { debug_ptr[DEBUG_ ## d]++; DSB(); } while (0) #else /* VCHIQ_ENABLE_DEBUG */ @@ -265,7 +265,8 @@ typedef struct remote_event_struct { int armed; int fired; - struct semaphore *event; + /* Contains offset from the beginning of the VCHIQ_STATE_T structure */ + uint32_t event; } REMOTE_EVENT_T; typedef struct opaque_platform_state_t *VCHIQ_PLATFORM_STATE_T; Index: contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c =================================================================== --- contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c (revision 328501) +++ contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c (working copy) @@ -47,7 +47,6 @@ #include #include -#include #include "vchiq_arm.h" #include "vchiq_2835.h" @@ -124,7 +123,7 @@ has completed */ if (event->armed) { /* trigger vc interrupt */ - dsb(); + DSB(); vchiq_write_4(0x48, 0); } } Index: contrib/vchiq/interface/vchiq_arm/vchiq_pagelist.h =================================================================== --- contrib/vchiq/interface/vchiq_arm/vchiq_pagelist.h (revision 328501) +++ contrib/vchiq/interface/vchiq_arm/vchiq_pagelist.h (working copy) @@ -42,11 +42,13 @@ #define PAGELIST_READ_WITH_FRAGMENTS 2 typedef struct pagelist_struct { - unsigned long length; - unsigned short type; - unsigned short offset; - unsigned long addrs[1]; /* N.B. 12 LSBs hold the number of following - pages at consecutive addresses. */ + uint32_t length; + uint16_t type; + uint16_t offset; + uint32_t addrs[1]; /* N.B. 12 LSBs hold the number + * of following pages at consecutive + * addresses. + */ } PAGELIST_T; #endif /* VCHIQ_PAGELIST_H */ Index: contrib/vchiq/interface/vchiq_arm/vchiq_shim.c =================================================================== --- contrib/vchiq/interface/vchiq_arm/vchiq_shim.c (revision 328501) +++ contrib/vchiq/interface/vchiq_arm/vchiq_shim.c (working copy) @@ -398,9 +398,17 @@ ***********************************************************/ int32_t vchi_held_msg_release(VCHI_HELD_MSG_T *message) { - vchiq_release_message((VCHIQ_SERVICE_HANDLE_T)message->service, - (VCHIQ_HEADER_T *)message->message); + /* + * Convert the service field pointer back to an + * VCHIQ_SERVICE_HANDLE_T which is an int. + * This pointer is opaque to everything except + * vchi_msg_hold which simply upcasted the int + * to a pointer. + */ + vchiq_release_message((VCHIQ_SERVICE_HANDLE_T)(long)message->service, + (VCHIQ_HEADER_T *)message->message); + return 0; } EXPORT_SYMBOL(vchi_held_msg_release); @@ -443,8 +451,16 @@ *data = header->data; *msg_size = header->size; + /* + * upcast the VCHIQ_SERVICE_HANDLE_T which is an int + * to a pointer and stuff it in the held message. + * This pointer is opaque to everything except + * vchi_held_msg_release which simply downcasts it back + * to an int. + */ + message_handle->service = - (struct opaque_vchi_service_t *)service->handle; + (struct opaque_vchi_service_t *)(long)service->handle; message_handle->message = header; return 0; Index: contrib/vchiq/interface/vchiq_arm/vchiq_util.c =================================================================== --- contrib/vchiq/interface/vchiq_arm/vchiq_util.c (revision 328501) +++ contrib/vchiq/interface/vchiq_arm/vchiq_util.c (working copy) @@ -80,6 +80,7 @@ return; while (queue->write == queue->read + queue->size) { + printf("%s:%d\n", __FILE__, __LINE__); if (down_interruptible(&queue->pop) != 0) { flush_signals(current); }