gb_control_timesync_get_last_event() sends a request asking for the
FrameTime at the last SVC strobe event. The responding entity returns the
FrameTime in the response phase of the request. Performing this operation
to an Interface after previously:
1. Synchronizing time using timesync-enable/timesync-authoritative
2. Sending an SVC_TIMESYNC_PING
will return the FrameTime of the responding entity at the SVC-ping. If
this command is sent before synchronization has been initiated or
successfully completed the responding entity should return an error
code.
- control.c::gb_control_timesync_get_last_event(u64 *frame_time)
Returns the FrameTime at the last SVC_TIMESYNC_PING to the AP Module.
Bryan O'Donoghue [Thu, 12 May 2016 11:43:50 +0000 (12:43 +0100)]
greybus: svc: Add TimeSync SVC commands
Simple addition of the TimeSync commands defined in the specification.
Adds:
- svc.c::timesync_enable(u8 count, u64 frame_time, u32 strobe_delay,
u32 refclk)
Commands the SVC to initiate count TimeSync strobe pulses with
strobe_delay microseconds delay between each strobe to the specified
bit-mask of Interface IDs indicated in a previous
timesync_wake_pins_acquire command. The frame_time parameter indicates
the initial time the SVC should base the first strobe from. The refclk
parameter indicates the APs clock rate, the SVC should ensure its own
clock ticks at this rate. Once enabled the SVC may not enter a low-power
mode which will result in the reference timer used to track time
switching off. The SVC will capture the authoritative FrameTime at each
strobe and store these values for later propagation to the AP with the
timesync_authoritative request.
- svc.c::timesync_disable(void)
Commands the SVC to immediately halt TimeSync logic. This will allow
the SVC to transition into low-power modes where the reference timer
being used for TimeSync may switch off.
- svc.c::timesync_authoritative(u64 *frame_time)
Used by the AP Module to ask the SVC for the authoritative FrameTime
as captured at each TimeSync strobe.
- svc.c::timesync_ping(u64 *frame_time)
Used by the AP Module to command the SVC to initiate a single strobe on
a specified bit-mask of Interface IDs communicated in a previous
timesync_wake_pins_acquire command. SVC will latch the FrameTime on the
rising edge of the outbound pulse and will return the FrameTime to the
AP Module in the response phase of the greybus transaction.
- svc::timesync_wake_pins_acquire(u32 strobe_mask)
Used by the AP to tell the SVC to set a bit-mask of wake lines associated
with a bit-mask of Interface IDs to a known initial state prior to the
SVC generating a TimeSync related pulse such as timesync-enable or
timesync-ping.
- svc::timesync_wake_pins_release(void)
Used by the AP to tell the SVC to release all wake-detect lines in the
timesync active state as previously specified in the
timesync_wake_pins_acquire operation.
Johan Hovold [Wed, 11 May 2016 08:18:06 +0000 (10:18 +0200)]
greybus: camera: fix data-connection handling
Now that core supports offloaded connections, we can remove the hack
that was used to setup the data connection.
Note that offloaded-resource management may need to be refined later,
but the current minimal implementation is enough to allow core to manage
the connections (e.g. needed for proper connection tear down and power
management).
This will also allow the camera driver to be converted to a bundle
driver.
Johan Hovold [Wed, 11 May 2016 08:18:04 +0000 (10:18 +0200)]
greybus: es2: add support for CDSI1 allocation
Use the new CPort-allocation callbacks to allow for rudimentary resource
management of the CDSI CPorts.
How to manage offloaded resources in a generic fashion is yet to be
determined, but this minimal implementation will allow core to manage
the camera data connection so that the current camera-driver hacks can
be removed. This is specifically required to be able to implement proper
connection closing and for power management.
Note that the CDSI CPorts can not (currently) be reset through the
USB vendor request.
Johan Hovold [Wed, 11 May 2016 08:18:02 +0000 (10:18 +0200)]
greybus: hd: generalise cport allocation
Generalise CPort allocation by allowing host-device drivers to override
the default implementation.
Also pass the connection flags down the stack as such information is
needed for proper CPort allocation. Specifically, this will initially be
used to allow the camera driver to allocate the dedicated CDSI CPorts.
Johan Hovold [Wed, 11 May 2016 08:17:59 +0000 (10:17 +0200)]
greybus: hd: move CPort allocation to host-device code
Move host-device CPort allocation to the host-device code.
Proper CPort allocation requires knowledge of the hardware and must be
handled by the host-device driver. This is an intermediate step that
moves the generic CPort-allocation code to the host-device code.
Viresh Kumar [Thu, 12 May 2016 05:56:48 +0000 (11:26 +0530)]
greybus: Fix probing of gpbridge devices
The gpbridge core tries to match the driver's id-table against all
CPorts available within the bundle for which the gpbridge bus was
created. The gpbdev here is unique for a cport_desc and only a single
cport_desc->protocol_id should be matched with the driver's id-table.
Fix it.
Tested on EVT 1.5 with a special manifest for GP module, where multiple
CPorts are part of the same Bridged PHY bundle.
Viresh Kumar [Thu, 12 May 2016 06:50:02 +0000 (12:20 +0530)]
greybus: gpbridge: Expose protocol_id in sysfs
Right now, userspace doesn't have any way to find what protocol does a
gpbridge device implement. And this is essential for the scripts to
know, to expect what kind of device will be present inside the gpbN
directory.
Expose 'protocol_id' in sysfs to fix that.
Tested by checking that the field appears with GP module on EVT 1.5.
Jeffrey Carlyle [Wed, 11 May 2016 17:08:55 +0000 (10:08 -0700)]
greybus: svc: support status in svc_intf_activate response
Update per Greybus spec. Status attribute added to activate
response to return more detailed information about errors during
activate. If the Greybus response is GB_OP_SUCCESS, the caller
must also check the status attribute in the response to determine
if any other errors occurred.
Testing done: along with matchine firmware change, verified that modules
were detected and enumerated as expected.
Viresh Kumar [Mon, 9 May 2016 05:29:01 +0000 (10:59 +0530)]
greybus: fw-download: Replace timer with delayed-work
The timeout-handlers need to call routines that can sleep and those
can't be called from interrupt context. The timer-handler is called in
interrupt context and so will hit a BUG() in vmalloc.c.
This patch moves away from timers to delayed-work, whose timeout handler
gets called in process context and can call the sleep-able routines
safely.
Note that this issue wasn't hit earlier when the initial patch for
timeouts was implemented due to some issues in the build arche_420. But
with the new build arche_440, the BUG started crashing the phone on
timeouts and so this fix is required.
Tested on EVT 1.5 by triggering fake timeouts, by not sending
release-firmware request for example. This is tested with build
arche_440.
Viresh Kumar [Mon, 9 May 2016 05:29:00 +0000 (10:59 +0530)]
greybus: bootrom: Implement timeouts to detect Module failures
Its possible that the Module may fail to download the next stage
firmware, or to jump into it and boot into the new personality.
We have already seen examples of both of these cases on EVT 1.5.
This patch implements timeouts in the bootrom bundle driver, which now
expects the next request from the Module to be received at the AP within
1 second of the previous request/response. The time interval can be
increased later if required.
The timeouts are added between:
- AP_READY and FIRMWARE_SIZE operations
- FIRMWARE_SIZE and GET_FIRMWARE operations
- Two GET_FIRMWARE operations
- GET_FIRMWARE and READY_TO_BOOT operations
- READY_TO_BOOT operation and the call to the ->disconnect() event of
the bootrom bundle (once the new hotplug request is received).
The timeout for the last case is kept at 5 seconds right now (random
value), as it may take a bit longer.
Because 'bootrom->fw' can be accessed simultaneously (from timeout
handler and incoming requests) and one of them can potentially free the
'->fw' structure, a mutex is also added to take care of such races while
accessing 'bootrom->fw' structure.
Also note that the '!bootrom->fw' check is moved to free_firmware()
routine.
Note that this version uses delayed-work (instead of timers used in
earlier attempt), as we need to call routines that can sleep from the
timeout handler.
Tested on EVT 1.5, by faking errors on certain requests, so that the
bootrom doesn't send any more requests. Normal case is working just fine
for audio and GP modules. This is tested with build arche_440.
Jeffrey Carlyle [Fri, 6 May 2016 19:43:53 +0000 (12:43 -0700)]
greybus: svc: implement svc_intf_activate
With upcoming firmware changes we will switch from an SVC-driven module
boot sequence to an AP-driven module sequence. This operation allows the
AP to request the SVC to boot a module to which the AP has previouslt
requested power be applied. This operation will also determine if the
remote interface is a dummy module, UniPro-only module, or full Greybus
module.
Testing done: Tested together with "new" firmware boot sequence to
verify that modules are detected and booted as expected.
With this patch gb_bootrom_timedout was getting called in interrupt
context and then proceeding to call functions that might block. In
practical terms, this was leading to a kernel BUG at mm/vmalloc.c:1650.
Signed-off-by: Jeffrey Carlyle <jcarlyle@google.com> Acked-by: Johan Hovold <johan@hovoldconsulting.com>
Viresh Kumar [Thu, 5 May 2016 10:03:20 +0000 (15:33 +0530)]
greybus: fw-download: Introduce timeouts for firmware downloads
As per greybus specification, the AP can apply, implementation
dependent, timeouts for:
- The time interval between the Find Firmware Response and the first
Fetch Firmware Request.
- The time interval between a Fetch Firmware Response and the next Fetch
Firmware Request.
- The time interval between a Fetch Firmware Response and the Release
Firmware Request.
- The time interval between the Find Firmware Response and the Release
Firmware Request.
This patch implements those timeouts.
The timeout period for the first three cases is fixed to one-second and
the timeout for the last one is finalized at runtime, dependent on the
total size of the firmware.
There can be two possible paths now, which may race for freeing or
getting the 'struct fw_request'. They are:
- Request handler: initiated from the Module side.
- Timeout handler: initiated on timeout of the programmed timer.
And so a mutex is added to avoid races.
Every caller which needs to access the 'struct fw_request' increments
the reference count, so that the structure doesn't get freed in
parallel. Once the structure is freed and reference is put by all the
users, the structure is freed.
If we timeout while waiting for a request from the Module, the AP frees
the 'struct fw_request', but does *not* free the request-id. This is
done to guarantee that a delayed request from the Module for the expired
id, doesn't get access to a new 'struct fw_request' allocated later with
the same id.
Tested with gbsim by hacking its code to delay the release request and
indefinitely fetch the same section of the firmware package. Both timed
out on the AP side and the 'struct fw_request' is free properly. Further
requests work fine after few are timed out. And rmmod (followed by more
similar testing) works just fine.
Viresh Kumar [Thu, 5 May 2016 10:03:19 +0000 (15:33 +0530)]
greybus: fw-download: Manage firmware requests with kref
This patch updates the fw-download core to manage firmware requests with
kref. This is required for the next patch, which will introduce timeouts
for firmware downloads.
greybus: arche-platform: Rework platform/wd-line state transition logic
This patch simplifies and improves the readability of the internal state
transition logic of arche platform driver state transition logic by:
1. Making a dedicated function to state-transition the platform code.
2. Condense the decision to swtich states down to a single switch
statement instead of four separate if/else clauses.
greybus: arche-platform: Export fn to allow timesync driver to change the state
With the addition of the timesync driver and looking at the hardware
interfaces we have, its clear we need to add a new arche-platform state.
This patch adds ARCHE_PLATFORM_STATE_TIME_SYNC to the arche-platform driver
to facilitate transition to the TIME_SYNC state if-and-only-if the
arche-platform driver is in the ACTIVE state.
This is mainly needed as wake/detect lines are shared between TIMESYNC
operation and basic control functionality of APBs. So during TIMESYNC
we want to make sure that the events on wake/detect lines are
ignored by the arche-platform APB reset logic.
This patch adds one exported function, which can be invoked from
timesync driver code, allowing, switching between
ARCHE_PLATFORM_STATE_TIME_SYNC <=> ARCHE_PLATFORM_STATE_ACTIVE states.
[ bryan.odonoghue@linaro.org: Added mutex, massaged commit text ]
With addition of exported function, required for TIMESYNC operation,
we need more locking mechanism for driver state, so to avoid confusion
rename existing spinlock variable to its appropriate name.
In order to verify TimeSync functionality we require a TimeSync-ping
operation where the AP can command the SVC to initiate a single strobe of
downstream TimeSync slaves, and report the FrameTime at the strobe. Ping
will only be valid after the system has transitioned to a TIMESYNC_ACTIVE
state.
In the active state each TimeSync slave will graph a single incoming SVC
strobe as a ping and will store its frame time. The AP will then gather
each last-event FrameTime for presentation to user-space in the AP and/or
further automation based on the reported FrameTimes at the SVC ping.
This patch adds the SVC ping command definition to greybus_protocols.h.
Its necessary to establish an initial state on the wake-detect lines before
enabling timesync on APB/GPB in order to ensure all GPIO edge-transitions are
correctly interpreted by the receiving processor.
This patch adds the operations defined in the Greybus specification to
greybus_protocols.h, this involves adding the
SVC_TIMESYNC_WAKE_PINS_ACQUIRE and SVC_TIMESYNC_WAKE_PINS_RELEASE commands
and moving the 'strobe_mask' parameter from 'struct
gb_svc_timesync_enable_request' to 'struct
gb_svc_timesync_wd_pins_acquire_request' since the communication of the
strobe_mask will be communicated before preparing any of the bridges to
receive the TimeSync pulses.
A separate patch to the greybus specification describes the transition
between the wake sub-state and the timesync sub-state.
Mitchell Tasman [Wed, 4 May 2016 21:30:23 +0000 (17:30 -0400)]
greybus: svc: reconfig APBridgeA-Switch link to handle required load
SW-4894, SW-4389, and share a common root cause, namely that
the power-on reset configuration of the APBridgeA-Switch link of PWM
Gear 1, 1 Lane, Slow Auto, is insufficient to handle some required
traffic loads, such as 3 audio streams plus boot-over-UniPro or 4 audio
streams.
The correct long-term solution is to implement a UniPro Power Mode
Manager as in that considers the demands placed on the network,
and adjusts power modes accordingly.
The present commit implements a short-term, brute-force hack to allow
continued system testing:
- Upon receiving an SVC HELLO request, schedule deferred work to
reconfigure the APB1-Switch link to PWM G2, 1 lane, Slow Auto
- When the Camera driver transitions a White Camera module from active to
inactive, return the APB1-Switch link to PWM G2, 1 lane, Slow Auto
The Camera driver already steps up the APBridgeA-Camera link speed while a
camera module is active, which affords sufficient margin for simultaneous
audio and hotplug activity, and the Camera driver already steps down the
link speed thereafter: the change made by the present patch is simply to
tweak the stepped-down power mode to match the new baseline configuration.
Viresh Kumar [Tue, 3 May 2016 10:43:12 +0000 (16:13 +0530)]
greybus: bootrom: Implement timeouts to detect Module failures
Its possible that the Module may fail to download the next stage
firmware, or to jump into it and boot into the new personality.
We have already seen examples of both of these cases on EVT 1.5.
This patch implements timeouts in the bootrom bundle driver, which now
expects the next request from the Module to be received at the AP within
1 second of the previous request/response. The time interval can be
increased later if required.
The timeouts are added between:
- AP_READY and FIRMWARE_SIZE operations
- FIRMWARE_SIZE and GET_FIRMWARE operations
- Two GET_FIRMWARE operations
- GET_FIRMWARE and READY_TO_BOOT operations
- READY_TO_BOOT operation and the call to the ->disconnect() event of
the bootrom bundle (once the new hotplug request is received).
The timeout for the last case is kept at 5 seconds right now (random
value), as it may take a bit longer.
Because 'bootrom->fw' can be accessed simultaneously (from timeout
handler and incoming requests) and one of them can potentially free the
'->fw' structure, a mutex is also added to take care of such races while
accessing 'bootrom->fw' structure.
Also note that the '!bootrom->fw' check is moved to free_firmware()
routine.
Tested on EVT 1.5, by faking errors on certain requests, so that the
bootrom doesn't send any more requests. Normal case is working just
fine for audio and GP modules.
Modify sequence of register_module & unregister_module in bundle
driver. This would affect the uevent generated for above user
space. Accordingly, we need to modify snd_soc_xxx sequence in
register_module() in codec driver.
Vaibhav Agarwal [Wed, 4 May 2016 10:59:21 +0000 (16:29 +0530)]
greybus: audio: Remove redundant lock protection & is_connected field
Each module maintains connected status & a lock to protect it.
Using codec->lock we can safely serialize ASoC specific callbacks
(in response to mixer_ctl update or dai_ops) and gb module
disconnect. Thus is_connected field can be removed.
Vaibhav Agarwal [Wed, 4 May 2016 10:59:19 +0000 (16:29 +0530)]
greybus: audio:gb_manager: Use proper locking around kobject_xxx
read/write_lock_irqsave mechanism was used to protect modules
list & kobject_xxx() in gb_audio_manager. Since kobject_xxx calls
can sleep spin_lock variants can't be used there. So use rw_sem
for protecting modules_list.
All firmware packages on the Modules or Interfaces are now managed by a
special Firmware Management Protocol. The Interface Manifest shall
at least contain the Firmware Management Bundle and a Firmware
Management Protocol CPort within it.
The bundle may contain additional CPorts based on the extra
functionality required to manage firmware packages.
For example, this is how the Firmware Management Bundle of the Interface
Manifest may look like:
This patch adds the basic firmware-management bundle driver, which just
creates a firmware-management connection. Support for individual
protocols will be added separately.
greybus: audio: Reorder gb_deactivate sequence to avoid protocol error
gb_activate_tx/rx is triggered from _prepare() & gb_deactivate
from shutdown(). This may cause protocol error in case shutdown
executes without _prepare due to some hw_params failure.
Also, reorganise _prepare & _shutdown calls to make it more
readable & cleaner.
David Lin [Sat, 23 Apr 2016 02:03:43 +0000 (19:03 -0700)]
greybus: svc: free pwrmon_rails memory upon exit
For every time SVC instance is created, memories for storing the rail IDs
are allocated, however, they are not freed when the SVC is destroyed.
This patch fixes the memory leak by freeing the memory when debugfs for
SVC is no longer needed.
Testing Done:
- Check pwrmon debugfs after turning on and off SVC
Signed-off-by: David Lin <dtwlin@google.com> Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
David Lin [Sat, 23 Apr 2016 02:03:42 +0000 (19:03 -0700)]
greybus: svc: clean up gb_svc struct for pwrmon
The power rail names and counts are unnecessarily stored in the gb_svc
structure once the SVC created, this causes waste of memory usage. This
patch removes rail names and rail counts storage from th gb_svc
structure.
Testing Done:
- Validated the readings from /d/greybus/1-svc/pwrmon/*
Signed-off-by: David Lin <dtwlin@google.com> Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Johan Hovold [Sat, 23 Apr 2016 16:47:31 +0000 (18:47 +0200)]
greybus: svc: implement interface mailbox event
Implement the new interface mailbox-event operation.
The event is sent by the SVC under certain conditions when an interface
updates its mailbox value. Specifically, this event will be used to
implement the new mode-switch functionality.
Upon reception the AP verifies that the interface is known and that the
mailbox has the expected MAILBOX_GREYBUS value. If so, the interface is
disabled before being re-enabled (re-enumerated).
Note that during mode-switch, the interface will typically already be in
a disabled state when the mailbox is written (with the ES3 bootrom being
the notable exception).
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Johan Hovold [Sat, 23 Apr 2016 16:47:30 +0000 (18:47 +0200)]
greybus: svc: implement module inserted and removed operations
Implement the new module inserted and removed operations.
The SVC sends these after detecting a module insertion or removal, and
in the former case after having determined the module geometry (i.e.
position and size).
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>