From ad255ee424e36f1fbf5e92e320328ceae1aecd49 Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Mon, 15 Aug 2011 11:59:47 -0700 Subject: [PATCH] Add a HAL representing a system-wide local time counter. This is a squashed merge of the following changes: commit 9def1ae65f6b4d6a8fdec147fdcd34f22f08174a Author: John Grossman Date: Fri Aug 12 11:47:20 2011 -0700 Change the signature of set_local_slew. Changed the definition of the slew function in the local time HAL to take an int16 instead of an int32 and to use the full range of the int instead of attempting to imply any particular PPM range. Change-Id: Ia67f50e77f1fe674a63ec69460e830d1191ef5a0 commit afab51327453d1bfc7423f8ce7a28933d8fc49b2 Author: John Grossman Date: Mon Jun 27 17:29:07 2011 -0700 Remove "primary" from the local_time HAL. Interface instances are a pattern which should only be used by audio. Remove its use from the local_time HAL. Change-Id: If4c458cf16a02d9dc63c04185111ae793fc57801 commit 1c26e59a66e75ccb31027f42183aaa32bde6e456 Author: John Grossman Date: Fri Jun 17 14:19:24 2011 -0700 Refactor the local/common clock services. This change is one of a set of 5 changes made to different repositories. Look for this comment in all of them. Refactor the local/common clock services to match android best practice. Notable changes include + The kernel no longer knows anything about common time. Common time has been moved completely up into user land. This has an impact on the accuracy of the timesync debugging code, and the netfilter assisted approach to network based timesync is going to have to be modified. + The timesync driver used by A@H is now just local time driver. + The kernel no longer needs access to the linear transform math code, and it has been removed. + A new HAL has been introduced to expose the concept of local time to the system. + A non-slewable stub implementation of the local time HAL based on CLOCK_MONOTONIC has been added. + The old library has been eliminated. Its functionality has been distributed among the common time binder service, the local time hal and the linear transform utility code. + All clients of the old library have been changed to be clients of the binder service, the hal and the utility code. + The reset_tt utilities have been removed, they no longer have a purpose in the system. Change-Id: I39843b94f9b6d13f63b22145a2edcafe4ca87349 Change-Id: Ib264c992d564b99ef7c7847a788e4fa7f5e101b4 Signed-off-by: Mike J. Chen Signed-off-by: John Grossman Conflicts: modules/Android.mk --- include/hardware/local_time_hal.h | 117 +++++++++++++++++++++++++++++++++++++ modules/Android.mk | 2 +- modules/local_time/Android.mk | 34 +++++++++++ modules/local_time/local_time_hw.c | 109 ++++++++++++++++++++++++++++++++++ 4 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 include/hardware/local_time_hal.h create mode 100644 modules/local_time/Android.mk create mode 100644 modules/local_time/local_time_hw.c diff --git a/include/hardware/local_time_hal.h b/include/hardware/local_time_hal.h new file mode 100644 index 0000000..6b6a317 --- /dev/null +++ b/include/hardware/local_time_hal.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_LOCAL_TIME_HAL_INTERFACE_H +#define ANDROID_LOCAL_TIME_HAL_INTERFACE_H + +#include + +#include + +__BEGIN_DECLS + +/** + * The id of this module + */ +#define LOCAL_TIME_HARDWARE_MODULE_ID "local_time" + +/** + * Name of the local time devices to open + */ +#define LOCAL_TIME_HARDWARE_INTERFACE "local_time_hw_if" + +/**********************************************************************/ + +/** + * A structure used to collect low level sync data in a lab environment. Most + * HAL implementations will never need this structure. + */ +struct local_time_debug_event { + int64_t local_timesync_event_id; + int64_t local_time; +}; + +/** + * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM + * and the fields of this data structure must begin with hw_module_t + * followed by module specific information. + */ +struct local_time_module { + struct hw_module_t common; +}; + +struct local_time_hw_device { + struct hw_device_t common; + + /** + * + * Returns the current value of the system wide local time counter + */ + int64_t (*get_local_time)(struct local_time_hw_device* dev); + + /** + * + * Returns the nominal frequency (in hertz) of the system wide local time + * counter + */ + uint64_t (*get_local_freq)(struct local_time_hw_device* dev); + + /** + * + * Sets the HW slew rate of oscillator which drives the system wide local + * time counter. On success, platforms should return 0. Platforms which + * do not support HW slew should leave this method set to NULL. + * + * Valid values for rate range from MIN_INT16 to MAX_INT16. Platform + * implementations should attempt map this range linearly to the min/max + * slew rate of their hardware. + */ + int (*set_local_slew)(struct local_time_hw_device* dev, int16_t rate); + + /** + * + * A method used to collect low level sync data in a lab environments. + * Most HAL implementations will simply set this member to NULL, or return + * -EINVAL to indicate that this functionality is not supported. + * Production HALs should never support this method. + */ + int (*get_debug_log)(struct local_time_hw_device* dev, + struct local_time_debug_event* records, + int max_records); +}; + +typedef struct local_time_hw_device local_time_hw_device_t; + +/** convenience API for opening and closing a supported device */ + +static inline int local_time_hw_device_open( + const struct hw_module_t* module, + struct local_time_hw_device** device) +{ + return module->methods->open(module, LOCAL_TIME_HARDWARE_INTERFACE, + (struct hw_device_t**)device); +} + +static inline int local_time_hw_device_close(struct local_time_hw_device* device) +{ + return device->common.close(&device->common); +} + + +__END_DECLS + +#endif // ANDROID_LOCAL_TIME_INTERFACE_H diff --git a/modules/Android.mk b/modules/Android.mk index 6231e78..c4c66da 100644 --- a/modules/Android.mk +++ b/modules/Android.mk @@ -1,2 +1,2 @@ -hardware_modules := gralloc hwcomposer audio nfc +hardware_modules := gralloc hwcomposer audio nfc local_time include $(call all-named-subdir-makefiles,$(hardware_modules)) diff --git a/modules/local_time/Android.mk b/modules/local_time/Android.mk new file mode 100644 index 0000000..f840dc7 --- /dev/null +++ b/modules/local_time/Android.mk @@ -0,0 +1,34 @@ +# Copyright (C) 2011 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH := $(call my-dir) + +# The default local time HAL module. The default module simply uses the +# system's clock_gettime(CLOCK_MONOTONIC) and does not support HW slewing. +# Devices which use the default implementation should take care to ensure that +# the oscillator backing the CLOCK_MONOTONIC implementation is phase locked to +# the audio and video output hardware. This default implementation is loaded +# if no other device specific modules are present. The exact load order can be +# seen in libhardware/hardware.c +# +# The format of the name is local_time..so +include $(CLEAR_VARS) + +LOCAL_MODULE := local_time.default +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw +LOCAL_SRC_FILES := local_time_hw.c +LOCAL_SHARED_LIBRARIES := liblog libcutils +LOCAL_MODULE_TAGS := optional + +include $(BUILD_SHARED_LIBRARY) diff --git a/modules/local_time/local_time_hw.c b/modules/local_time/local_time_hw.c new file mode 100644 index 0000000..a1f5d43 --- /dev/null +++ b/modules/local_time/local_time_hw.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "local_time_hw_default" +//#define LOG_NDEBUG 0 + +#include +#include +#include +#include + +#include + +#include +#include + +struct stub_local_time_device { + struct local_time_hw_device device; +}; + +static int64_t ltdev_get_local_time(struct local_time_hw_device* dev) +{ + struct timespec ts; + uint64_t now; + int ret; + + ret = clock_gettime(CLOCK_MONOTONIC, &ts); + if (ret < 0) { + LOGW("%s failed to fetch CLOCK_MONOTONIC value! (res = %d)", + dev->common.module->name, ret); + return 0; + } + + now = (((uint64_t)ts.tv_sec) * 1000000000ull) + + ((uint64_t)ts.tv_nsec); + + return (int64_t)now; +} + +static uint64_t ltdev_get_local_freq(struct local_time_hw_device* dev) +{ + // For better or worse, linux clock_gettime routines normalize all clock + // frequencies to 1GHz + return 1000000000ull; +} + +static int ltdev_close(hw_device_t *device) +{ + free(device); + return 0; +} + +static int ltdev_open(const hw_module_t* module, const char* name, + hw_device_t** device) +{ + struct stub_local_time_device *ltdev; + struct timespec ts; + int ret; + + if (strcmp(name, LOCAL_TIME_HARDWARE_INTERFACE) != 0) + return -EINVAL; + + ltdev = calloc(1, sizeof(struct stub_local_time_device)); + if (!ltdev) + return -ENOMEM; + + ltdev->device.common.tag = HARDWARE_DEVICE_TAG; + ltdev->device.common.version = 0; + ltdev->device.common.module = (struct hw_module_t *) module; + ltdev->device.common.close = ltdev_close; + + ltdev->device.get_local_time = ltdev_get_local_time; + ltdev->device.get_local_freq = ltdev_get_local_freq; + ltdev->device.set_local_slew = NULL; + ltdev->device.get_debug_log = NULL; + + *device = <dev->device.common; + + return 0; +} + +static struct hw_module_methods_t hal_module_methods = { + .open = ltdev_open, +}; + +struct local_time_module HAL_MODULE_INFO_SYM = { + .common = { + .tag = HARDWARE_MODULE_TAG, + .version_major = 1, + .version_minor = 0, + .id = LOCAL_TIME_HARDWARE_MODULE_ID, + .name = "Default local_time HW HAL", + .author = "The Android Open Source Project", + .methods = &hal_module_methods, + }, +}; -- 2.11.0