]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
greybus: svc: Add TimeSync SVC commands
authorBryan O'Donoghue <bryan.odonoghue@linaro.org>
Thu, 12 May 2016 11:43:50 +0000 (12:43 +0100)
committerGreg Kroah-Hartman <gregkh@google.com>
Sat, 14 May 2016 16:26:24 +0000 (18:26 +0200)
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.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Vaibhav Hiremath <vaibhav.hiremath@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/svc.c
drivers/staging/greybus/svc.h

index 3bdf778d6d5d8fbebc5852cae3aa6998b04d699e..80e8cf04ade9899ee9f3841d2e78bf66bd115763 100644 (file)
@@ -459,6 +459,91 @@ void gb_svc_connection_destroy(struct gb_svc *svc, u8 intf1_id, u16 cport1_id,
 }
 EXPORT_SYMBOL_GPL(gb_svc_connection_destroy);
 
+int gb_svc_timesync_enable(struct gb_svc *svc, u8 count, u64 frame_time,
+                          u32 strobe_delay, u32 refclk)
+{
+       struct gb_connection *connection = svc->connection;
+       struct gb_svc_timesync_enable_request request;
+
+       request.count = count;
+       request.frame_time = cpu_to_le64(frame_time);
+       request.strobe_delay = cpu_to_le32(strobe_delay);
+       request.refclk = cpu_to_le32(refclk);
+       return gb_operation_sync(connection,
+                                GB_SVC_TYPE_TIMESYNC_ENABLE,
+                                &request, sizeof(request), NULL, 0);
+}
+EXPORT_SYMBOL_GPL(gb_svc_timesync_enable);
+
+int gb_svc_timesync_disable(struct gb_svc *svc)
+{
+       struct gb_connection *connection = svc->connection;
+
+       return gb_operation_sync(connection,
+                                GB_SVC_TYPE_TIMESYNC_DISABLE,
+                                NULL, 0, NULL, 0);
+}
+EXPORT_SYMBOL_GPL(gb_svc_timesync_disable);
+
+int gb_svc_timesync_authoritative(struct gb_svc *svc, u64 *frame_time)
+{
+       struct gb_connection *connection = svc->connection;
+       struct gb_svc_timesync_authoritative_response response;
+       int ret, i;
+
+       ret = gb_operation_sync(connection,
+                               GB_SVC_TYPE_TIMESYNC_AUTHORITATIVE, NULL, 0,
+                               &response, sizeof(response));
+       if (ret < 0)
+               return ret;
+
+       for (i = 0; i < GB_TIMESYNC_MAX_STROBES; i++)
+               frame_time[i] = le64_to_cpu(response.frame_time[i]);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(gb_svc_timesync_authoritative);
+
+int gb_svc_timesync_ping(struct gb_svc *svc, u64 *frame_time)
+{
+       struct gb_connection *connection = svc->connection;
+       struct gb_svc_timesync_ping_response response;
+       int ret;
+
+       ret = gb_operation_sync(connection,
+                               GB_SVC_TYPE_TIMESYNC_PING,
+                               NULL, 0,
+                               &response, sizeof(response));
+       if (ret < 0)
+               return ret;
+
+       *frame_time = le64_to_cpu(response.frame_time);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(gb_svc_timesync_ping);
+
+int gb_svc_timesync_wake_pins_acquire(struct gb_svc *svc, u32 strobe_mask)
+{
+       struct gb_connection *connection = svc->connection;
+       struct gb_svc_timesync_wake_pins_acquire_request request;
+
+       request.strobe_mask = cpu_to_le32(strobe_mask);
+       return gb_operation_sync(connection,
+                                GB_SVC_TYPE_TIMESYNC_WAKE_PINS_ACQUIRE,
+                                &request, sizeof(request),
+                                NULL, 0);
+}
+EXPORT_SYMBOL_GPL(gb_svc_timesync_wake_pins_acquire);
+
+int gb_svc_timesync_wake_pins_release(struct gb_svc *svc)
+{
+       struct gb_connection *connection = svc->connection;
+
+       return gb_operation_sync(connection,
+                                GB_SVC_TYPE_TIMESYNC_WAKE_PINS_RELEASE,
+                                NULL, 0, NULL, 0);
+}
+EXPORT_SYMBOL_GPL(gb_svc_timesync_wake_pins_release);
+
 /* Creates bi-directional routes between the devices */
 int gb_svc_route_create(struct gb_svc *svc, u8 intf1_id, u8 dev1_id,
                               u8 intf2_id, u8 dev2_id)
index 7268db6e26436990fb452fbcc082f463c3d5f8c2..e3e0aa14b08da5ef0759ba8027f2d2cec44ffe7d 100644 (file)
@@ -85,6 +85,13 @@ void gb_svc_watchdog_destroy(struct gb_svc *svc);
 bool gb_svc_watchdog_enabled(struct gb_svc *svc);
 int gb_svc_watchdog_enable(struct gb_svc *svc);
 int gb_svc_watchdog_disable(struct gb_svc *svc);
+int gb_svc_timesync_enable(struct gb_svc *svc, u8 count, u64 frame_time,
+                          u32 strobe_delay, u32 refclk);
+int gb_svc_timesync_disable(struct gb_svc *svc);
+int gb_svc_timesync_authoritative(struct gb_svc *svc, u64 *frame_time);
+int gb_svc_timesync_ping(struct gb_svc *svc, u64 *frame_time);
+int gb_svc_timesync_wake_pins_acquire(struct gb_svc *svc, u32 strobe_mask);
+int gb_svc_timesync_wake_pins_release(struct gb_svc *svc);
 
 int gb_svc_protocol_init(void);
 void gb_svc_protocol_exit(void);