android 13 from xiaosuan
This commit is contained in:
commit
6cdeb5a31c
|
|
@ -0,0 +1,16 @@
|
|||
#
|
||||
# Based on /build/soong/scripts/system-clang-format
|
||||
#
|
||||
BasedOnStyle: Google
|
||||
Standard: Cpp11
|
||||
AccessModifierOffset: -2
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
ColumnLimit: 100
|
||||
CommentPragmas: NOLINT:.*
|
||||
DerivePointerAlignment: false
|
||||
IncludeBlocks: Preserve
|
||||
IndentWidth: 4
|
||||
ContinuationIndentWidth: 8
|
||||
PointerAlignment: Left
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2018 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.
|
||||
|
||||
soong_namespace {}
|
||||
|
||||
// *** THIS PACKAGE HAS SPECIAL LICENSING CONDITIONS. PLEASE
|
||||
// CONSULT THE OWNERS AND opensource-licensing@google.com BEFORE
|
||||
// DEPENDING ON IT IN YOUR PROJECT. ***
|
||||
package {
|
||||
default_applicable_licenses: ["device_amlogic_yukawa_license"],
|
||||
}
|
||||
|
||||
// Added automatically by a large-scale-change that took the approach of
|
||||
// 'apply every license found to every target'. While this makes sure we respect
|
||||
// every license restriction, it may not be entirely correct.
|
||||
//
|
||||
// e.g. GPL in an MIT project might only apply to the contrib/ directory.
|
||||
//
|
||||
// Please consider splitting the single license below into multiple licenses,
|
||||
// taking care not to lose any license_kind information, and overriding the
|
||||
// default license using the 'licenses: [...]' property on targets as needed.
|
||||
//
|
||||
// For unused files, consider creating a 'fileGroup' with "//visibility:private"
|
||||
// to attach the license to, and including a comment whether the files may be
|
||||
// used in the current project.
|
||||
// See: http://go/android-license-faq
|
||||
license {
|
||||
name: "device_amlogic_yukawa_license",
|
||||
visibility: [":__subpackages__"],
|
||||
license_kinds: [
|
||||
"SPDX-license-identifier-Apache-2.0",
|
||||
"SPDX-license-identifier-GPL-2.0",
|
||||
"legacy_by_exception_only", // by exception only
|
||||
],
|
||||
// large-scale-change unable to identify any license_text files
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
#
|
||||
# Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
# WARNING: Everything listed here will be built on ALL platforms,
|
||||
# including x86, the emulator, and the SDK. Modules must be uniquely
|
||||
# named (liblights.panda), and must build everywhere, or limit themselves
|
||||
# to only building on ARM if they include assembly. Individual makefiles
|
||||
# are responsible for having their own logic, for fine-grained control.
|
||||
|
||||
ifneq ($(filter yukawa%, $(TARGET_DEVICE)),)
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
$(eval $(call declare-1p-copy-files,device/amlogic/yukawa/binaries/bt-wifi-firmware,))
|
||||
$(eval $(call declare-1p-copy-files,device/amlogic/yukawa/binaries/video_firmware,))
|
||||
$(eval $(call declare-1p-copy-files,device/amlogic/yukawa/hal/audio,))
|
||||
$(eval $(call declare-1p-copy-files,device/amlogic/yukawa/hal/camera,))
|
||||
$(eval $(call declare-1p-copy-files,device/amlogic/yukawa/input,))
|
||||
$(eval $(call declare-1p-copy-files,device/amlogic/yukawa/media_xml,))
|
||||
$(eval $(call declare-1p-copy-files,device/amlogic/yukawa/wifi,))
|
||||
$(eval $(call declare-1p-copy-files,device/amlogic/yukawa/,.rc))
|
||||
$(eval $(call declare-1p-copy-files,device/amlogic/yukawa/,fstab.yukawa))
|
||||
|
||||
# if some modules are built directly from this directory (not subdirectories),
|
||||
# their rules should be written here.
|
||||
|
||||
include $(call all-makefiles-under,$(LOCAL_PATH))
|
||||
endif
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#
|
||||
# Copyright (C) 2017 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.
|
||||
#
|
||||
|
||||
PRODUCT_MAKEFILES := \
|
||||
$(LOCAL_DIR)/yukawa_sei510.mk \
|
||||
$(LOCAL_DIR)/yukawa32_sei510.mk \
|
||||
$(LOCAL_DIR)/yukawa.mk \
|
||||
$(LOCAL_DIR)/yukawa32.mk
|
||||
|
||||
COMMON_LUNCH_CHOICES := \
|
||||
yukawa_sei510-userdebug \
|
||||
yukawa-userdebug
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
#
|
||||
# Product-specific compile-time definitions.
|
||||
#
|
||||
# The generic product target doesn't have any hardware-specific pieces.
|
||||
# Primary Arch
|
||||
TARGET_ARCH := arm64
|
||||
TARGET_ARCH_VARIANT := armv8-a
|
||||
TARGET_CPU_ABI := arm64-v8a
|
||||
TARGET_CPU_VARIANT := cortex-a53
|
||||
|
||||
# Secondary Arch
|
||||
TARGET_2ND_ARCH := arm
|
||||
TARGET_2ND_ARCH_VARIANT := armv8-a
|
||||
TARGET_2ND_CPU_ABI := armeabi-v7a
|
||||
TARGET_2ND_CPU_ABI2 := armeabi
|
||||
TARGET_2ND_CPU_VARIANT := cortex-a53
|
||||
|
||||
TARGET_USES_64_BIT_BINDER := true
|
||||
TARGET_SUPPORTS_64_BIT_APPS := true
|
||||
|
||||
TARGET_BOARD_PLATFORM := yukawa
|
||||
|
||||
# Vulkan
|
||||
BOARD_INSTALL_VULKAN := true
|
||||
|
||||
# OpenCL
|
||||
BOARD_INSTALL_OPENCL := true
|
||||
|
||||
# BT configs
|
||||
BOARD_HAVE_BLUETOOTH := true
|
||||
|
||||
# generic wifi
|
||||
WPA_SUPPLICANT_VERSION := VER_0_8_X
|
||||
BOARD_WPA_SUPPLICANT_DRIVER := NL80211
|
||||
BOARD_HOSTAPD_DRIVER := NL80211
|
||||
|
||||
# Treble
|
||||
PRODUCT_FULL_TREBLE_OVERRIDE := true
|
||||
BOARD_VNDK_VERSION := current
|
||||
|
||||
# AVB
|
||||
ifeq ($(TARGET_AVB_ENABLE), true)
|
||||
BOARD_AVB_ENABLE := true
|
||||
else
|
||||
BOARD_AVB_ENABLE := false
|
||||
endif
|
||||
|
||||
TARGET_NO_BOOTLOADER := true
|
||||
TARGET_NO_KERNEL := false
|
||||
|
||||
ifeq ($(TARGET_USE_AB_SLOT), true)
|
||||
BOARD_USES_RECOVERY_AS_BOOT := true
|
||||
AB_OTA_UPDATER := true
|
||||
|
||||
AB_OTA_PARTITIONS += \
|
||||
boot \
|
||||
system \
|
||||
vendor \
|
||||
vbmeta
|
||||
endif
|
||||
|
||||
BOARD_BOOTIMAGE_PARTITION_SIZE := 33554432
|
||||
BOARD_DTBOIMG_PARTITION_SIZE := 8388608 # 8 MiB
|
||||
BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE ?= ext4
|
||||
BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
|
||||
ifneq ($(TARGET_USE_AB_SLOT), true)
|
||||
BOARD_CACHEIMAGE_PARTITION_SIZE := 268435456
|
||||
BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
|
||||
endif
|
||||
TARGET_USERIMAGES_USE_EXT4 := true
|
||||
TARGET_COPY_OUT_VENDOR := vendor
|
||||
|
||||
# Super partition
|
||||
TARGET_USE_DYNAMIC_PARTITIONS := true
|
||||
BOARD_BUILD_SUPER_IMAGE_BY_DEFAULT := true
|
||||
BOARD_SUPER_PARTITION_GROUPS := db_dynamic_partitions
|
||||
BOARD_DB_DYNAMIC_PARTITIONS_PARTITION_LIST := system vendor
|
||||
ifeq ($(TARGET_USE_AB_SLOT), true)
|
||||
BOARD_SUPER_PARTITION_SIZE := 4831838208
|
||||
else
|
||||
BOARD_SUPER_PARTITION_SIZE := 2415919104
|
||||
endif
|
||||
BOARD_DB_DYNAMIC_PARTITIONS_SIZE := 2411724800 # Reserve 4M for DAP metadata
|
||||
BOARD_SUPER_PARTITION_METADATA_DEVICE := super
|
||||
# BOARD_SUPER_IMAGE_IN_UPDATE_PACKAGE := true
|
||||
|
||||
|
||||
# Recovery
|
||||
TARGET_RECOVERY_PIXEL_FORMAT := RGBX_8888
|
||||
ifeq ($(TARGET_AVB_ENABLE), true)
|
||||
ifeq ($(TARGET_USE_AB_SLOT), true)
|
||||
TARGET_RECOVERY_FSTAB := device/amlogic/yukawa/fstab.yukawa.avb.ab
|
||||
else
|
||||
TARGET_RECOVERY_FSTAB := device/amlogic/yukawa/fstab.recovery.yukawa.avb
|
||||
BOARD_RECOVERYIMAGE_PARTITION_SIZE := 33554432
|
||||
endif
|
||||
BOARD_AVB_RECOVERY_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
|
||||
BOARD_AVB_RECOVERY_ALGORITHM := SHA256_RSA2048
|
||||
BOARD_AVB_RECOVERY_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
|
||||
BOARD_AVB_RECOVERY_ROLLBACK_INDEX_LOCATION := 2
|
||||
else
|
||||
ifeq ($(TARGET_USE_AB_SLOT), true)
|
||||
TARGET_RECOVERY_FSTAB := device/amlogic/yukawa/fstab.yukawa
|
||||
else
|
||||
TARGET_RECOVERY_FSTAB := device/amlogic/yukawa/fstab.recovery.yukawa
|
||||
BOARD_RECOVERYIMAGE_PARTITION_SIZE := 33554432
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
BOARD_KERNEL_OFFSET := 0x1080000
|
||||
BOARD_KERNEL_TAGS_OFFSET := 0x1000000
|
||||
BOARD_INCLUDE_DTB_IN_BOOTIMG := true
|
||||
BOARD_MKBOOTIMG_ARGS := --kernel_offset $(BOARD_KERNEL_OFFSET)
|
||||
BOARD_BOOT_HEADER_VERSION := 2
|
||||
BOARD_MKBOOTIMG_ARGS += --header_version $(BOARD_BOOT_HEADER_VERSION)
|
||||
|
||||
# Pass unsigned dtbo image (generated by build/tasks/dtimages.mk) to Android
|
||||
# build system for AVB signing
|
||||
DTBO_UNSIGNED := dtbo-unsigned.img
|
||||
# $(PRODUCT_OUT) hasn't been defined yet, so use "=" instead of ":="
|
||||
# so that it is resolved later
|
||||
BOARD_PREBUILT_DTBOIMAGE = $(PRODUCT_OUT)/$(DTBO_UNSIGNED)
|
||||
|
||||
|
||||
BOARD_KERNEL_CMDLINE += no_console_suspend console=ttyAML0,115200 earlycon
|
||||
BOARD_KERNEL_CMDLINE += printk.devkmsg=on
|
||||
BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/ffe07000.mmc
|
||||
BOARD_KERNEL_CMDLINE += init=/init
|
||||
BOARD_KERNEL_CMDLINE += firmware_class.path=/vendor/firmware
|
||||
BOARD_KERNEL_CMDLINE += androidboot.hardware=yukawa
|
||||
ifneq ($(TARGET_SELINUX_ENFORCE), true)
|
||||
BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive
|
||||
endif
|
||||
ifeq ($(TARGET_BUILTIN_EDID), true)
|
||||
BOARD_KERNEL_CMDLINE += drm.edid_firmware=edid/1920x1080.bin
|
||||
endif
|
||||
ifneq ($(TARGET_SENSOR_MEZZANINE),)
|
||||
BOARD_KERNEL_CMDLINE += overlay_mgr.overlay_dt_entry=hardware_cfg_$(TARGET_SENSOR_MEZZANINE)
|
||||
endif
|
||||
ifneq ($(TARGET_MEM_SIZE),)
|
||||
BOARD_KERNEL_CMDLINE += mem=$(TARGET_MEM_SIZE)
|
||||
endif
|
||||
|
||||
ifneq ($(TARGET_KERNEL_CFG),)
|
||||
BOARD_KERNEL_CMDLINE += $(TARGET_KERNEL_CFG)
|
||||
endif
|
||||
|
||||
USE_E2FSPROGS := true
|
||||
|
||||
BOARD_USES_GENERIC_AUDIO := false
|
||||
BOARD_USES_ALSA_AUDIO := true
|
||||
TARGET_USES_MKE2FS := true
|
||||
TARGET_USES_HWC2 := true
|
||||
BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR := device/amlogic/yukawa/bluetooth
|
||||
|
||||
BOARD_SEPOLICY_DIRS += \
|
||||
device/amlogic/yukawa/sepolicy
|
||||
|
||||
DEVICE_MANIFEST_FILE += device/amlogic/yukawa/manifest.xml
|
||||
|
||||
ifneq ($(TARGET_KERNEL_USE), 4.19)
|
||||
DEVICE_MANIFEST_FILE += device/amlogic/yukawa/manifest_kernel5.xml
|
||||
endif
|
||||
DEVICE_MATRIX_FILE := device/amlogic/yukawa/compatibility_matrix.xml
|
||||
|
||||
ifneq ($(TARGET_SENSOR_MEZZANINE),)
|
||||
DEVICE_MANIFEST_FILE += device/amlogic/yukawa/sensorhal/manifest.xml
|
||||
endif
|
||||
|
||||
# Generate an APEX image for experiment b/119800099.
|
||||
DEXPREOPT_GENERATE_APEX_IMAGE := true
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
# Copyright 2017 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.
|
||||
#
|
||||
|
||||
# If you don't need to do a full clean build but would like to touch
|
||||
# a file or delete some intermediate files, add a clean step to the end
|
||||
# of the list. These steps will only be run once, if they haven't been
|
||||
# run before.
|
||||
#
|
||||
# E.g.:
|
||||
# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
|
||||
# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
|
||||
#
|
||||
# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
|
||||
# files that are missing or have been moved.
|
||||
#
|
||||
# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
|
||||
# Use $(OUT_DIR) to refer to the "out" directory.
|
||||
#
|
||||
# If you need to re-do something that's already mentioned, just copy
|
||||
# the command and add it to the bottom of the list. E.g., if a change
|
||||
# that you made last week required touching a file and a change you
|
||||
# made today requires touching the same file, just copy the old
|
||||
# touch step and add it to the end of the list.
|
||||
#
|
||||
# ************************************************
|
||||
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
|
||||
# ************************************************
|
||||
|
||||
# For example:
|
||||
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
|
||||
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
|
||||
#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
|
||||
#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
|
||||
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor)
|
||||
|
||||
# Remove /system/lib[64]/vndk-sp/libz.so
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/vndk-sp/libz.so)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/vndk-sp/libz.so)
|
||||
|
||||
# Remove /product mount point
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/product)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product)
|
||||
|
||||
# Remove android.hardware.audio*@2.0 implementation
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/lib/hw/android.hardware.audio*@2.0-impl.so)
|
||||
|
||||
# Adds product.img
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/product)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/fonts)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/usr)
|
||||
|
||||
# Remove default android.hardware.health@2.0-service.yukawa
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/bin/hw/android.hardware.health@2.0-service.yukawa)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/init/android.hardware.health@2.0-service.yukawa.rc)
|
||||
|
||||
# Remove healthd
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/healthd)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/init/healthd.rc)
|
||||
|
||||
# Remove Codec2.0 software process
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/hw/hardware.google.media.c2@1.0-service-software)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/init/hardware.google.media.c2@1.0-service-software.rc)
|
||||
|
||||
# Remove keymaster service
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/init/android.hardware.keymaster@4.0-service*)
|
||||
|
||||
# Migrate to versioned VNDK directory
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/vndk-sp)
|
||||
|
||||
#AU300 cleanup
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/include)
|
||||
|
||||
# Remove /product mount point
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/product)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product)
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# *** THIS PACKAGE HAS SPECIAL LICENSING CONDITIONS. PLEASE
|
||||
# CONSULT THE OWNERS AND opensource-licensing@google.com BEFORE
|
||||
# DEPENDING ON IT IN YOUR PROJECT. ***
|
||||
third_party {
|
||||
license_type: BY_EXCEPTION_ONLY
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[Options]
|
||||
ignore_merged_commits = true
|
||||
|
||||
[Builtin Hooks]
|
||||
clang_format = true
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(call all-makefiles-under,$(LOCAL_PATH))
|
||||
|
|
@ -0,0 +1 @@
|
|||
include $(call all-subdir-makefiles)
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#
|
||||
# Copyright 2019, 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)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_VENDOR_MODULE := true
|
||||
|
||||
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
|
||||
LOCAL_SDK_VERSION := current
|
||||
LOCAL_EXPORT_PACKAGE_RESOURCES := true
|
||||
LOCAL_PROGUARD_ENABLED := disabled
|
||||
LOCAL_USE_AAPT2 := true
|
||||
LOCAL_AAPT2_ONLY := true
|
||||
|
||||
LOCAL_PACKAGE_NAME := YukawaAndroidOverlay
|
||||
LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
|
||||
LOCAL_LICENSE_CONDITIONS := notice
|
||||
LOCAL_CERTIFICATE := platform
|
||||
include $(BUILD_RRO_PACKAGE)
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<!--
|
||||
~ Copyright (C) 2019 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.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="android.yukawa"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
<overlay android:targetPackage="android" android:priority="0" android:isStatic="true"/>
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** Copyright 2019, 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<!-- Mapping of keycodes to components which will be handled globally.
|
||||
Modify this file to add global keys.
|
||||
The key will NOT go to the foreground application and instead only ever be sent via targeted
|
||||
broadcast to the specified component. The action of the intent will be
|
||||
android.intent.action.GLOBAL_BUTTON and the KeyEvent will be included in the intent as
|
||||
android.intent.extra.KEY_EVENT.
|
||||
-->
|
||||
|
||||
<global_keys version="1">
|
||||
<!-- Example format: id = keycode to handle globally. component = component which will handle this key. -->
|
||||
<key keyCode="KEYCODE_PAIRING" component="com.google.android.yukawaservice/.RemoteSyncReceiver" />
|
||||
</global_keys>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#
|
||||
# Copyright 2017 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)
|
||||
include $(call all-makefiles-under,$(LOCAL_PATH))
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,222 @@
|
|||
#AP6398S_NVRAM_V1.1_20170926
|
||||
# BCM4359 WLBGA iPA, iLNA board for bringup -AP6359SA_V1.0NVRAM
|
||||
NVRAMRev=$Rev: 528206 $
|
||||
cckdigfilttype=5
|
||||
#cckdigfilttype=4 (default)
|
||||
#valid ofdm filter types are 0 and 1
|
||||
ofdmfilttype_2gbe=127
|
||||
ofdmfilttype_5gbe=127
|
||||
sromrev=11
|
||||
boardrev=0x1301
|
||||
boardtype=0x0812
|
||||
# JIRA:SW4349-945 MANDATORY! Update makefile in case you touch bfl
|
||||
#boardflags=0x10081201
|
||||
boardflags=0x00480201
|
||||
boardflags2=0x40801000
|
||||
boardflags3=0x48700106
|
||||
#boardnum=57410
|
||||
macaddr=00:90:4c:27:80:01
|
||||
ccode=0
|
||||
regrev=0
|
||||
antswitch=0
|
||||
pdgain5g=0
|
||||
pdgain2g=0
|
||||
lowpowerrange2g=0
|
||||
lowpowerrange5g=0
|
||||
tworangetssi2g=0
|
||||
tworangetssi5g=0
|
||||
# Low Power Range start value: 0dBm
|
||||
olpc_thresh2g=0
|
||||
olpc_thresh5g=0
|
||||
AvVmid_c0=2,130,2,130,2,130,2,130,2,130
|
||||
AvVmid_c1=2,130,2,130,2,130,2,130,2,130
|
||||
# JIRA:SW4349-945 MANDATORY! Update makefile in case you touch femctl
|
||||
femctrl=14
|
||||
vendid=0x14e4
|
||||
devid=0x43ef
|
||||
manfid=0x2d0
|
||||
#prodid=0x052e
|
||||
nocrc=1
|
||||
btc_mode=1
|
||||
#btc_params82=0x1a0
|
||||
otpimagesize=502
|
||||
xtalfreq=37400
|
||||
rxgains2gelnagaina0=3
|
||||
rxgains2gtrisoa0=7
|
||||
rxgains2gtrelnabypa0=1
|
||||
rxgains5gelnagaina0=3
|
||||
rxgains5gtrisoa0=6
|
||||
rxgains5gtrelnabypa0=1
|
||||
rxgains5gmelnagaina0=3
|
||||
rxgains5gmtrisoa0=6
|
||||
rxgains5gmtrelnabypa0=1
|
||||
rxgains5ghelnagaina0=3
|
||||
rxgains5ghtrisoa0=6
|
||||
rxgains5ghtrelnabypa0=1
|
||||
rxgains2gelnagaina1=3
|
||||
rxgains2gtrisoa1=7
|
||||
rxgains2gtrelnabypa1=1
|
||||
rxgains5gelnagaina1=3
|
||||
rxgains5gtrisoa1=6
|
||||
rxgains5gtrelnabypa1=1
|
||||
rxgains5gmelnagaina1=3
|
||||
rxgains5gmtrisoa1=6
|
||||
rxgains5gmtrelnabypa1=1
|
||||
rxgains5ghelnagaina1=3
|
||||
rxgains5ghtrisoa1=6
|
||||
rxgains5ghtrelnabypa1=1
|
||||
rxchain=3
|
||||
txchain=3
|
||||
aa2g=3
|
||||
aa5g=3
|
||||
agbg0=2
|
||||
agbg1=2
|
||||
aga0=2
|
||||
aga1=2
|
||||
tssipos2g=1
|
||||
extpagain2g=2
|
||||
tssipos5g=1
|
||||
extpagain5g=2
|
||||
tempthresh=255
|
||||
tempoffset=255
|
||||
rawtempsense=0x1ff
|
||||
fdss_interp_en=1
|
||||
#fdss_level_2g=3,3
|
||||
fdss_level_5g=4,4
|
||||
#pa2gccka0=-186,8076,-976
|
||||
#pa2gccka1=-217,7061,-881
|
||||
#pa2gccka2=-67,9864,-1253
|
||||
#pa2gccka3=-115,9164,-1225
|
||||
#pa2ga0=-196,6950,-832
|
||||
#pa2ga1=-204,6710,-809
|
||||
#pa2ga2=-220,4557,-593
|
||||
#pa2ga3=-218,4596,-601
|
||||
pa2ga0=-193,7335,-862
|
||||
pa2ga1=-202,6968,-828
|
||||
pa2ga2=-220,4685,-607
|
||||
pa2ga3=-218,4724,-615
|
||||
#pa5ga0=-191,6865,-844,-169,7525,-907,-168,7768,-938,-192,7073,-871
|
||||
#pa5ga1=-182,7580,-919,-188,7614,-931,-219,6536,-818,-202,7220,-895
|
||||
#pa5ga2=-220,4437,-628,-183,5005,-678,-229,4048,-551,-223,4448,-611
|
||||
#pa5ga3=-263,3914,-566,-224,4649,-640,-230,4385,-596,-154,6488,-866
|
||||
pa5ga0=-205,6664,-820,-201,6801,-835,-199,6767,-831,-178,7266,-873
|
||||
pa5ga1=-200,7025,-858,-193,7170,-871,-186,7290,-879,-187,7227,-873
|
||||
pa5ga2=-220,4616,-647,-183,5184,-694,-229,4227,-571,-223,4627,-631
|
||||
pa5ga3=-263,4170,-599,-224,4905,-668,-230,4641,-625,-154,6744,-885
|
||||
#pa5gbw4080a0=-201,6883,-859,-198,7088,-881,-202,6968,-870,-210,6522,-820
|
||||
#pa5gbw4080a1=-217,6626,-832,-201,7517,-932,-201,7251,-896,-184,7500,-917
|
||||
#pa5gbw4080a2=-272,3585,-525,-193,5404,-740,-229,4201,-572,-230,4036,-550
|
||||
#pa5gbw4080a3=-278,3361,-486,-230,4794,-662,-268,3605,-508,-276,3337,-478
|
||||
maxp2ga0=74
|
||||
maxp2ga1=74
|
||||
maxp5ga0=70,70,70,70
|
||||
maxp5ga1=70,70,71,70
|
||||
subband5gver=0x4
|
||||
paparambwver=3
|
||||
pdoffset2g40mvalid=0
|
||||
cckpwroffset0=0x3
|
||||
cckpwroffset1=0x3
|
||||
pdoffset2g40ma0=0x2
|
||||
pdoffset2g40ma1=0x3
|
||||
pdoffset40ma0=0x0022
|
||||
pdoffset80ma0=0xceff
|
||||
pdoffset40ma1=0x0123
|
||||
pdoffset80ma1=0xdfff
|
||||
cckbw202gpo=0
|
||||
cckbw20ul2gpo=0
|
||||
mcsbw202gpo=0x44444444
|
||||
mcsbw402gpo=0x44444444
|
||||
dot11agofdmhrbw202gpo=0x2222
|
||||
ofdmlrbw202gpo=0x0000
|
||||
mcsbw205glpo=0x44444444
|
||||
mcsbw405glpo=0x44444444
|
||||
mcsbw805glpo=0xCCCCCCCC
|
||||
mcsbw1605glpo=0
|
||||
mcsbw205gmpo=0x44444444
|
||||
mcsbw405gmpo=0x44444444
|
||||
mcsbw805gmpo=0xCCCCCCCC
|
||||
mcsbw1605gmpo=0
|
||||
mcsbw205ghpo=0x44444444
|
||||
mcsbw405ghpo=0x44444444
|
||||
mcsbw805ghpo=0xCCCCCCCC
|
||||
mcsbw1605ghpo=0
|
||||
mcslr5glpo=0x0000
|
||||
mcslr5gmpo=0x0000
|
||||
mcslr5ghpo=0x0000
|
||||
sb20in40hrpo=0x0
|
||||
sb20in80and160hr5glpo=0x0
|
||||
sb40and80hr5glpo=0x0
|
||||
sb20in80and160hr5gmpo=0x0
|
||||
sb40and80hr5gmpo=0x0
|
||||
sb20in80and160hr5ghpo=0x0
|
||||
sb40and80hr5ghpo=0x0
|
||||
sb20in40lrpo=0x0
|
||||
sb20in80and160lr5glpo=0x0
|
||||
sb40and80lr5glpo=0x0
|
||||
sb20in80and160lr5gmpo=0x0
|
||||
sb40and80lr5gmpo=0x0
|
||||
sb20in80and160lr5ghpo=0x0
|
||||
sb40and80lr5ghpo=0x0
|
||||
dot11agduphrpo=0x0
|
||||
dot11agduplrpo=0x0
|
||||
phycal_tempdelta=255
|
||||
temps_period=15
|
||||
temps_hysteresis=15
|
||||
ltecxmux=0
|
||||
ltecxpadnum=0x0504
|
||||
ltecxfnsel=0x44
|
||||
ltecxgcigpio=0x04
|
||||
#OOB params
|
||||
#device_wake_opt=1
|
||||
#host_wake_opt=0
|
||||
swctrlmap_2g=0x00000808,0x00001010,0x00001010,0x021010,0x3ff
|
||||
swctrlmapext_2g=0x00000000,0x00000000,0x00000000,0x000000,0x003
|
||||
swctrlmap_5g=0x00004040,0x00000000,0x00000000,0x000000,0x3e5
|
||||
swctrlmapext_5g=0x00000000,0x00000101,0x00000101,0x000000,0x003
|
||||
fem_table_init_val=0x00001010,0x00000000
|
||||
rssi_delta_5gl_c0=3,3,2,2,5,5
|
||||
rssi_delta_5gml_c0=0,2,0,2,3,5
|
||||
rssi_delta_5gmu_c0=0,2,0,2,3,5
|
||||
rssi_delta_5gh_c0=2,5,2,5,5,8
|
||||
rssi_delta_5gl_c1=1,1,2,2,3,3
|
||||
rssi_delta_5gml_c1=-1,1,0,2,1,3
|
||||
rssi_delta_5gmu_c1=-1,1,0,2,1,3
|
||||
rssi_delta_5gh_c1=0,3,2,5,3,6
|
||||
rssi_delta_2g_c0=4,5,4,5
|
||||
rssi_delta_2g_c1=2,3,2,3
|
||||
#muxenab=1
|
||||
#avs_enab=1
|
||||
|
||||
# ########### BTC Dynctl profile params ############
|
||||
# flags:bit0 - dynctl enabled, bit1 dynamic desense, bit2 dynamic mode
|
||||
btcdyn_flags=0x0
|
||||
#btcdyn_dflt_dsns_level=0
|
||||
#btcdyn_low_dsns_level=0
|
||||
#btcdyn_mid_dsns_level=7
|
||||
#btcdyn_high_dsns_level=2
|
||||
#btcdyn_default_btc_mode=5
|
||||
#btcdyn_btrssi_hyster=2
|
||||
# --- number of rows in the array vars below ---
|
||||
#btcdyn_msw_rows=3
|
||||
#btcdyn_dsns_rows=2
|
||||
# --- mode switch data rows (max is 4) ---
|
||||
#btcdyn_msw_row0=1,8,0,-50,-100
|
||||
#btcdyn_msw_row1=1,4,0,-55,-100
|
||||
#btcdyn_msw_row2=1,0,0,-70,-100
|
||||
#btcdyn_msw_row3=1,-4,0,-70,-100
|
||||
# --- desense switching data rows (max is 4) ---
|
||||
#btcdyn_dsns_row0=5,8,0,-40,-40
|
||||
#btcdyn_dsns_row0=5,4,0,-60,-60
|
||||
#btcdyn_dsns_row1=5,0,0,0,-75
|
||||
powoffs2gtna0=1,3,3,1,0,0,1,2,2,2,1,1,0,0
|
||||
powoffs2gtna1=-1,1,1,1,0,0,1,2,3,2,2,0,0,0
|
||||
#new Jan 4th
|
||||
#eps_shift0=-1,-6,-1,-5
|
||||
#eps_shift1=-4,-6,-1,-2
|
||||
#eps_shift2=-1,9,-2,-6
|
||||
muxenab=0x10
|
||||
|
||||
#bandedge
|
||||
fdss_level_2g=4,4
|
||||
fdss_level_5g=5,5
|
||||
fdss_interp_en=1
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
TARGET := ${GPU_TYPE}
|
||||
GPU_TARGET_PLATFORM ?= default_8a
|
||||
GPU_DRV_VERSION ?= r16p0
|
||||
LOCAL_ANDROID_VERSION_NUM := p-${GPU_DRV_VERSION}gralloc1
|
||||
|
||||
LOCAL_MODULE := libGLES_mali
|
||||
LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
|
||||
LOCAL_LICENSE_CONDITIONS := notice
|
||||
LOCAL_MULTILIB := both
|
||||
LOCAL_MODULE_SUFFIX := .so
|
||||
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
|
||||
ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 26 && echo OK),OK)
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/egl
|
||||
LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib/egl
|
||||
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64/egl
|
||||
else
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
|
||||
LOCAL_MODULE_PATH_32 := $(TARGET_OUT)/lib/egl
|
||||
LOCAL_MODULE_PATH_64 := $(TARGET_OUT)/lib64/egl
|
||||
endif
|
||||
ifeq ($(TARGET_2ND_ARCH),)
|
||||
ifeq ($(TARGET_ARCH),arm)
|
||||
LOCAL_SRC_FILES := $(TARGET)/libGLES_mali_$(GPU_TARGET_PLATFORM)_32-$(LOCAL_ANDROID_VERSION_NUM).so
|
||||
else
|
||||
LOCAL_SRC_FILES := $(TARGET)/libGLES_mali_$(GPU_TARGET_PLATFORM)_64-$(LOCAL_ANDROID_VERSION_NUM).so
|
||||
endif
|
||||
else
|
||||
LOCAL_SRC_FILES_32 := $(TARGET)/libGLES_mali_$(GPU_TARGET_PLATFORM)_32-$(LOCAL_ANDROID_VERSION_NUM).so
|
||||
LOCAL_SRC_FILES_64 := $(TARGET)/libGLES_mali_$(GPU_TARGET_PLATFORM)_64-$(LOCAL_ANDROID_VERSION_NUM).so
|
||||
endif
|
||||
LOCAL_SHARED_LIBRARIES := android.hardware.graphics.common@1.0 libz libnativewindow libc++ liblog libm libc libdl
|
||||
LOCAL_STRIP_MODULE := false
|
||||
|
||||
ifeq ($(BOARD_INSTALL_VULKAN),true)
|
||||
LOCAL_POST_INSTALL_CMD = $(hide) \
|
||||
pushd $(dir $(LOCAL_INSTALLED_MODULE))../hw && \
|
||||
ln -sf ../egl/$(notdir $(LOCAL_INSTALLED_MODULE)) vulkan.$(TARGET_DEVICE).so && \
|
||||
popd;
|
||||
endif
|
||||
|
||||
ifeq ($(BOARD_INSTALL_OPENCL),true)
|
||||
LOCAL_POST_INSTALL_CMD += \
|
||||
pushd $(dir $(LOCAL_INSTALLED_MODULE)).. && \
|
||||
ln -sf egl/$(notdir $(LOCAL_INSTALLED_MODULE)) libOpenCL.so.1.1 && \
|
||||
ln -sf libOpenCL.so.1.1 libOpenCL.so.1 && \
|
||||
ln -sf libOpenCL.so.1.1 libOpenCL.so && \
|
||||
popd;
|
||||
endif
|
||||
|
||||
include $(BUILD_PREBUILT)
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
LES-PRE-20769
|
||||
SP-Version: 1.0
|
||||
25 November 2015
|
||||
|
||||
END USER LICENCE AGREEMENT FOR THE MALI USERSPACE DRIVER ("Mali DRIVER")
|
||||
|
||||
THIS END USER LICENCE AGREEMENT ("LICENCE") IS A LEGAL AGREEMENT
|
||||
BETWEEN YOU (EITHER A SINGLE INDIVIDUAL, OR SINGLE LEGAL ENTITY) AND
|
||||
ARM LIMITED ("ARM") FOR THE USE OF THE SOFTWARE ACCOMPANYING THIS
|
||||
LICENCE. ARM IS ONLY WILLING TO LICENSE THE SOFTWARE TO YOU ON
|
||||
CONDITION THAT YOU ACCEPT ALL OF THE TERMS IN THIS LICENCE. BY
|
||||
INSTALLING OR OTHERWISE USING OR COPYING THE SOFTWARE YOU INDICATE
|
||||
THAT YOU AGREE TO BE BOUND BY ALL OF THE TERMS OF THIS LICENCE. IF YOU
|
||||
DO NOT AGREE TO THE TERMS OF THIS LICENCE, ARM IS UNWILLING TO LICENSE
|
||||
THE SOFTWARE TO YOU AND YOU MAY NOT INSTALL, USE OR COPY THE SOFTWARE,
|
||||
AND YOU SHOULD PROMPTLY RETURN THE SOFTWARE TO YOUR SUPPLIER.
|
||||
|
||||
"Applications" means applications for use solely in conjunction with
|
||||
Mali-based products manufactured under licence from ARM.
|
||||
|
||||
"Output" means data resulting from your use of the Software and all
|
||||
direct and indirect derivatives thereof.
|
||||
|
||||
"Software" means any software, firmware and data accompanying this
|
||||
Licence, any printed, electronic or online documentation supplied with
|
||||
it under the terms of this Licence for the Mali Driver.
|
||||
|
||||
1. LICENCE GRANTS TO YOU.
|
||||
|
||||
1.1 ARM hereby grants to you, subject to the terms and conditions of
|
||||
this Licence, a non-exclusive, non-transferable, revocable, worldwide
|
||||
licence to:
|
||||
|
||||
(i) use and copy the Software or certain components or optional
|
||||
functionality in the Software, as applicable, solely for the
|
||||
purposes of running, designing or developing Applications; and
|
||||
|
||||
(ii) subject to Clause 1.2, distribute the whole of the Software;
|
||||
and/or (b) the whole or any part of the Software together
|
||||
with, or as incorporated into, Applications; and
|
||||
|
||||
1.2 If you choose to redistribute the whole or any part of the
|
||||
Software pursuant to the licences granted in Clause 1.1(ii), you
|
||||
agree: (i) not to use ARM's or any of its licensors names, logos or
|
||||
trademarks to market Applications; (ii) to retain any and all
|
||||
copyright notices and other notices (whether ARM's or its licensor's)
|
||||
which are included with the Software; and (iii) include a copy of this
|
||||
Licence with such redistribution.
|
||||
|
||||
2. RESTRICTIONS ON USE OF THE SOFTWARE.
|
||||
|
||||
BENCHMARKING: This Licence does not prevent you from using the
|
||||
Software for benchmarking purposes. However, you shall ensure that any
|
||||
and all benchmarking data relating to the Software, and any other
|
||||
results of your use or testing of the Software which are indicative of
|
||||
its performance, efficacy, reliability or quality, shall not be used
|
||||
to disparage ARM, its products or services, or in a manner that, in
|
||||
ARM's reasonable judgment, may diminish or otherwise damage the
|
||||
reputation of ARM.
|
||||
|
||||
COPYRIGHT AND RESERVATION OF RIGHTS: The Software is owned by ARM or
|
||||
its licensors and is protected by copyright and other intellectual
|
||||
property laws and international treaties. The Software is licensed not
|
||||
sold. You acquire no rights to the Software other than as expressly
|
||||
provided by this Licence. You shall not remove from the Software any
|
||||
copyright notice or other notice and shall ensure that any such notice
|
||||
is reproduced in any copies of the whole or any part of the Software
|
||||
made by you or other permitted users.
|
||||
|
||||
REVERSE ENGINEERING: Except to the extent that such activity is
|
||||
permitted by applicable law you shall not reverse engineer, decompile
|
||||
or disassemble any of the Software. If the Software was provided to
|
||||
you in Europe you shall not reverse engineer, decompile or disassemble
|
||||
any of the Software for the purposes of error correction.
|
||||
|
||||
RESTRICTED USE: You agree that you shall not use the Software or the
|
||||
Output other than pursuant to and in accordance with the exercise of
|
||||
any of the licences granted under this Licence. Without limiting the
|
||||
generality of the foregoing, you shall not use the Software or any
|
||||
Output: (a) for determining if any features, functions or processes
|
||||
provided by the Software are covered by any patents or patent
|
||||
applications owned by you or a third party; or (b) for developing
|
||||
technology, applications or products which avoid any of ARM's
|
||||
intellectual property in the Software licensed hereunder; or (c) as a
|
||||
reference for modifying existing patents or patent applications or
|
||||
creating any continuation, continuation in part, or extension of
|
||||
existing patents or patent applications.
|
||||
|
||||
3. SUPPORT.
|
||||
|
||||
ARM is not under an obligation to provide support, but it may do so at
|
||||
its own discretion, and if it does, it will only be in respect of the
|
||||
Software as delivered.
|
||||
|
||||
4. NO WARRANTIES.
|
||||
|
||||
YOU AGREE THAT THE SOFTWARE IS LICENSED "AS IS", AND THAT ARM
|
||||
EXPRESSLY DISCLAIMS ALL REPRESENTATIONS, WARRANTIES, CONDITIONS OR
|
||||
OTHER TERMS, EXPRESS OR IMPLIED OR STATUTORY, INCLUDING WITHOUT
|
||||
LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, SATISFACTORY
|
||||
QUALITY, AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
YOU EXPRESSLY ASSUME ALL LIABILITIES AND RISKS, FOR USE OR OPERATION
|
||||
OF APPLICATIONS, INCLUDING WITHOUT LIMITATION, APPLICATIONS DESIGNED
|
||||
OR INTENDED FOR MISSION CRITICAL APPLICATIONS, SUCH AS PACEMAKERS,
|
||||
WEAPONRY, AIRCRAFT NAVIGATION, FACTORY CONTROL SYSTEMS, ETC. SHOULD
|
||||
THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE ENTIRE COST OF ALL
|
||||
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
5. LIMITATION OF LIABILITY.
|
||||
|
||||
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
|
||||
ARM BE LIABLE FOR ANY INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING LOSS OF PROFITS) ARISING OUT OF THE USE OR
|
||||
INABILITY TO USE THE SOFTWARE WHETHER BASED ON A CLAIM UNDER CONTRACT,
|
||||
TORT OR OTHER LEGAL THEORY, EVEN IF ARM WAS ADVISED OF THE POSSIBILITY
|
||||
OF SUCH DAMAGES.
|
||||
|
||||
ARM does not seek to limit or exclude liability for death or personal
|
||||
injury arising from ARM's negligence or ARM's fraud and because some
|
||||
jurisdictions do not permit the exclusion or limitation of liability
|
||||
for consequential or incidental damages the above limitation relating
|
||||
to liability for consequential damages may not apply to you.
|
||||
|
||||
NOTWITHSTANDING ANYTHING TO THE CONTRARY CONTAINED IN THIS LICENCE,
|
||||
THE MAXIMUM LIABILITY OF ARM TO YOU IN AGGREGATE FOR ALL CLAIMS MADE
|
||||
AGAINST ARM IN CONTRACT TORT OR OTHERWISE UNDER OR IN CONNECTION WITH
|
||||
THE SUBJECT MATTER OF THIS LICENCE SHALL NOT EXCEED THE GREATER OF:
|
||||
(I) THE TOTAL OF SUMS PAID BY YOU TO ARM (IF ANY) FOR THIS LICENCE;
|
||||
AND (II) $10.00 USD. THE EXISTENCE OF MORE THAN ONE CLAIM WILL NOT
|
||||
ENLARGE OR EXTEND THE LIMIT.
|
||||
|
||||
6. U.S. GOVERNMENT END USERS.
|
||||
|
||||
US Government Restrictions: Use, duplication, reproduction, release,
|
||||
modification, disclosure or transfer of the Software is restricted in
|
||||
accordance with the terms of this Licence.
|
||||
|
||||
7. TERM AND TERMINATION.
|
||||
|
||||
This Licence shall remain in force until terminated by you or by ARM.
|
||||
Without prejudice to any of its other rights if you are in breach of
|
||||
any of the terms and conditions of this Licence then ARM may terminate
|
||||
this Licence immediately upon giving written notice to you or on
|
||||
thirty (30) days written notice without cause. You may terminate this
|
||||
Licence at any time. Upon termination of this Licence by you or by ARM
|
||||
, you shall stop using the Software and destroy all copies of the
|
||||
Software in your possession, together with all documentation and
|
||||
related materials. The provisions of clauses 2, 3, 4, 5, 6, 7, and 8
|
||||
shall survive termination of this Licence.
|
||||
|
||||
8. GENERAL.
|
||||
|
||||
This Licence is governed by English Law. Except where ARM agrees
|
||||
otherwise in: (i) a written contract signed by you and ARM; or (ii) a
|
||||
written contract provided by ARM and accepted by you, this is the only
|
||||
agreement between you and ARM relating to the Software and it may only
|
||||
be modified by written agreement between you and ARM. Except as
|
||||
expressly agreed in writing, this Licence may not be modified by
|
||||
purchase orders, advertising or other representation by any person. If
|
||||
any clause or sentence in this Licence is held by a court of law to be
|
||||
illegal or unenforceable the remaining provisions of this Licence
|
||||
shall not be affected thereby. The failure by ARM to enforce any of
|
||||
the provisions of this Licence, unless waived in writing, shall not
|
||||
constitute a waiver of ARM's rights to enforce such provision or any
|
||||
other provision of this Licence in the future.
|
||||
|
||||
At ARM's request, you agree to check your computers for installations
|
||||
of the Software and any other information requested by ARM relating to
|
||||
Software installation and to provide this information to ARM. You
|
||||
agree that auditors nominated by ARM may also perform such checking
|
||||
and reporting on behalf of ARM by prior appointment during your normal
|
||||
business hours on seven (7) days' notice. ARM shall bear the auditors'
|
||||
costs for that audit unless it reveals unlicensed usage in which case
|
||||
you shall promptly reimburse ARM for all reasonable costs and
|
||||
expenses, including professional fees, relating to such audit. Any
|
||||
information which is disclosed to ARM or such auditors during checking
|
||||
or audit shall be treated as your confidential information and shall
|
||||
only be used by ARM for licence management, compliance and enforcement
|
||||
purposes.
|
||||
|
||||
The Software provided under this Agreement is subject to U.K.,
|
||||
European Union, and U.S. export control laws and regulations,
|
||||
including the U.S. Export Administration Act and its associated
|
||||
regulations (hereafter collectively referred to as "Export
|
||||
Regulations"). LICENSEE agrees to comply fully with all such Export
|
||||
Regulations and LICENSEE agrees that it shall not, either directly or
|
||||
indirectly, export in breach of the Export Regulations, any Software
|
||||
received under this Agreement, nor any direct products thereof; (i) to
|
||||
any country, company or person subject to export restrictions or
|
||||
sanctions under the Export Regulations; or (ii) for any prohibited end
|
||||
use, which at the time of export requires an export license or other
|
||||
governmental approval, without first obtaining such license or
|
||||
approval.
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
this is Android GPU Library
|
||||
|
||||
GPU_TARGET_PLATFORM is the same as the Kernel.
|
||||
cpu kernel android GPU_TARGET_PLATFORM
|
||||
cortex-a9 32bit 32bit default_7a
|
||||
cortex-a53 32bit 32bit default_7a
|
||||
cortex-a53 64bit 32bit default_8a
|
||||
cortex-a53 64bit 64bit default_8a
|
||||
|
||||
GPU_TARGET_PLATFORM?= default_7a
|
||||
|
||||
library symbols was put at
|
||||
ftp://ftp-china.amlogic.com/mbox/gpu-lib/
|
||||
|
||||
ddk git
|
||||
|
||||
git clone ssh://android@10.8.9.5/platform/hardware/gpu/mali/ddk -b aml-64bit-r5p1
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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 _BDROID_BUILDCFG_H
|
||||
#define _BDROID_BUILDCFG_H
|
||||
|
||||
#define BTA_DM_COD \
|
||||
{ 0x2C, 0x04, 0x14 }
|
||||
#define BTA_AV_SINK_INCLUDED TRUE
|
||||
|
||||
#define BLE_VND_INCLUDED TRUE
|
||||
|
||||
// Turn off BLE_LOCAL_PRIVACY_ENABLED. Remote reconnect fails on
|
||||
// often if this is enabled.
|
||||
#define BLE_LOCAL_PRIVACY_ENABLED FALSE
|
||||
|
||||
/* minimum acceptable connection interval */
|
||||
#define BTM_BLE_CONN_INT_MIN_LIMIT 0x0006 /*7.5ms=6*1.25*/
|
||||
|
||||
/*fix bt crash about init */
|
||||
#define KERNEL_MISSING_CLOCK_BOOTTIME_ALARM TRUE
|
||||
|
||||
#define BTM_BLE_CONN_INT_MIN_DEF 6
|
||||
#define BTM_BLE_CONN_INT_MAX_DEF 12
|
||||
#define BTM_BLE_SCAN_SLOW_INT_1 64
|
||||
#define BTM_BLE_SCAN_SLOW_WIN_1 16
|
||||
|
||||
#define BTA_SKIP_BLE_READ_REMOTE_FEAT TRUE
|
||||
#define BLE_DELAY_REQUEST_ENC TRUE
|
||||
|
||||
#define BTA_AV_SINK_INCLUDED TRUE
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
Build Yukawa userdebug image:
|
||||
=============================
|
||||
|
||||
$ . ./build/envsetup.sh
|
||||
$ lunch yukawa-userdebug
|
||||
$ make -j24
|
||||
|
||||
- For VIM3L: make TARGET_VIM3L=true -j24
|
||||
|
||||
Compile Kernel:
|
||||
===============
|
||||
|
||||
$ git clone https://android.googlesource.com/kernel/hikey-linaro
|
||||
$ export PATH=$ANDROID_BUILD_TOP/prebuilts/clang/host/linux-x86/clang-r365631c/bin:$PATH
|
||||
|
||||
$ cd hikey-linaro
|
||||
$ git checkout -b android-amlogic-bmeson-4.19 origin/android-amlogic-bmeson-4.19
|
||||
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-android- CLANG_TRIPLE=aarch64-linux-gnu- CC=clang meson_defconfig
|
||||
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-android- CLANG_TRIPLE=aarch64-linux-gnu- CC=clang -j24
|
||||
$ lz4c -f arch/arm64/boot/Image arch/arm64/boot/Image.lz4
|
||||
$ cp arch/arm64/boot/Image.lz4 $ANDROID_BUILD_TOP/device/amlogic/yukawa-kernel
|
||||
$ cp arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dtb $ANDROID_BUILD_TOP/device/amlogic/yukawa-kernel
|
||||
$ cp arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dtb $ANDROID_BUILD_TOP/device/amlogic/yukawa-kernel
|
||||
$ cp arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dtb $ANDROID_BUILD_TOP/device/amlogic/yukawa-kernel
|
||||
|
||||
$ cd <Path-to-AOSP>; rm out/target/product/yukawa/boot.img out/target/product/yukawa/kernel
|
||||
$ make bootimage -j24
|
||||
|
||||
$ fastboot flash boot out/target/product/yukawa/boot.img
|
||||
|
||||
- For VIM3L: make TARGET_VIM3L=true bootimage -j24
|
||||
- If yukawa-userdebug build was not launched, set direct path to aarch64:
|
||||
$ export PATH=$ANDROID_BUILD_TOP/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin:$PATH
|
||||
|
||||
Recover Bootloader:
|
||||
===================
|
||||
Link to 'update' utility: https://github.com/khadas/utils/tree/master/aml-flash-tool/tools/linux-x86
|
||||
|
||||
- Enter USB recovery mode by pressing USB Boot Button and turning Power ON
|
||||
- For VIM3L:
|
||||
-- Use u-boot_kvim3l_noab.bin rather than u-boot_sei610.bin.
|
||||
-- Enter recovery / upgrade mode by pressing function button 3 times in 2s.
|
||||
|
||||
$ update write u-boot_sei610.bin 0xfffa0000 0x10000
|
||||
$ update run 0xfffa0000
|
||||
$ update bl2_boot u-boot_sei610.bin
|
||||
$ fastboot oem format
|
||||
$ fastboot flash bootloader u-boot_sei610.bin
|
||||
$ fastboot erase bootenv
|
||||
$ fastboot reboot-bootloader
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
require board=sei510
|
||||
require version-bootloader=U-Boot 2021.07-00051-g79f19c6307
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
require board=sei610
|
||||
require version-bootloader=U-Boot 2021.07-00051-g79f19c6307
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
require board=vim3
|
||||
require version-bootloader=U-Boot 2021.07-00051-g79f19c6307
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
require board=vim3l
|
||||
require version-bootloader=U-Boot 2021.07-00051-g79f19c6307
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
Build Mainline u-boot - bl33:
|
||||
=============================
|
||||
|
||||
Main Wiki Page : https://gitlab.com/baylibre/amlogic/atv/u-boot/wikis/home
|
||||
|
||||
Download the toolchain : gcc-linaro-7.2.1-2017.11-x86_64_aarch64-elf
|
||||
http://releases.linaro.org/components/toolchain/binaries/7.2-2017.11/aarch64-elf/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-elf.tar.xz
|
||||
|
||||
Download U-Boot Source Code From :
|
||||
https://gitlab.com/baylibre/amlogic/atv/u-boot.git
|
||||
|
||||
actual tag : u-boot/v2021.07/integ-20210712
|
||||
dev branch : u-boot/v2021.07/integ
|
||||
|
||||
link to U-Boot aosp release wiki page :
|
||||
https://gitlab.com/baylibre/amlogic/atv/u-boot/wikis/U-Boot-for-Yukawa-Release
|
||||
|
||||
Compile:
|
||||
|
||||
export PATH=<path-to-toolchain>/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-elf/bin:$PATH
|
||||
export CROSS_COMPILE=aarch64-elf-
|
||||
git clone https://gitlab.com/baylibre/amlogic/atv/u-boot.git
|
||||
cd u-boot
|
||||
git checkout u-boot/v2021.07/integ-20210712
|
||||
make [sei510|sei610|sei610_ab|khadas-vim3_android|khadas-vim3_android_ab|khadas-vim3l_android|khadas-vim3l_android_ab]_defconfig
|
||||
make
|
||||
|
||||
Generate fip binary
|
||||
===================
|
||||
|
||||
use tarball in fip_packages folder and untar it
|
||||
|
||||
- For sei510 (yukawa_sei510):
|
||||
tar -xaf fip-collect-g12a-g12a_u200_v1-amlogic-dev_9.2.1811_21-20191203-113239.tar.gz
|
||||
|
||||
- For sei610 (yukawa):
|
||||
tar -xaf fip-collect-g12a-sm1_ac214_v1-amlogic-dev_9.2.1811_21-20191204-161855.tar.gz
|
||||
|
||||
- For VIM3L (yukawa):
|
||||
tar -xaf fip-collect-g12a-kvim3l-khadas-vims-pie-20210111-211224.tar.gz
|
||||
|
||||
- For VIM3 (yukawa):
|
||||
tar -xaf fip-collect-g12b-kvim3-khadas-vims-pie-20210111-211833.tar.gz
|
||||
|
||||
Then launch script for scripts folder:
|
||||
|
||||
./generate-bins-new.sh <fip-collect-directory> <target-bl33-binary>
|
||||
|
||||
flash result with:
|
||||
fastboot flash bootloader uboot-bins/u-boot.bin
|
||||
fastboot erase bootenv
|
||||
fastboot reboot bootloader
|
||||
|
||||
after reboot if partitions table need to be updated:
|
||||
fastboot oem format
|
||||
|
||||
More informations to update and flash bootloader on Yukawa:
|
||||
https://gitlab.com/baylibre/amlogic/atv/u-boot/wikis/U-Boot-for-Yukawa
|
||||
|
||||
|
||||
Generate new fip_packages for Khadas VIM3/3L
|
||||
=============================================
|
||||
|
||||
- Launch collect script for script foler :
|
||||
./collect-khadas_binaries-git-refboard.sh <khadas-uboot-branch> <soc> <refboard>
|
||||
|
||||
branch to use for VIM3/3L : khadas-vims-pie
|
||||
soc VIM3 : g12b
|
||||
VIM3L: sm1
|
||||
|
||||
refboard VIM3 : kvim3
|
||||
VIM3L: kvim3l
|
||||
|
||||
- Generate tarball :
|
||||
Example:
|
||||
tar -czf fip-collect-g12b-kvim3-khadas-vims-pie-20210111-211833.tar.gz fip-collect-g12b-kvim3-khadas-vims-pie-20210111-211833
|
||||
|
||||
Adapt folder name with folder generate by collect script.
|
||||
|
||||
- to generate fip bin cf "Generate fip binary"
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,121 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
set -o nounset
|
||||
|
||||
set -o xtrace
|
||||
|
||||
# The goal of this script is gather all binaries provides by AML in order to generate
|
||||
# our final u-boot image from the u-boot.bin (bl33)
|
||||
#
|
||||
# Some binaries come from the u-boot vendor kernel (bl21, acs, bl301)
|
||||
# Others from the buildroot package (aml_encrypt tool, bl2.bin, bl30)
|
||||
|
||||
function usage() {
|
||||
echo "Usage: $0 [openlinux branch] [soc] [refboard]"
|
||||
}
|
||||
|
||||
if [[ $# -lt 3 ]]
|
||||
then
|
||||
usage
|
||||
exit 22
|
||||
fi
|
||||
|
||||
GITBRANCH=${1}
|
||||
SOCFAMILY=${2}
|
||||
REFBOARD=${3}
|
||||
|
||||
if [[ "$SOCFAMILY" == "sm1" ]]
|
||||
then
|
||||
SOCFAMILY="g12a"
|
||||
fi
|
||||
|
||||
if ! [[ "$SOCFAMILY" == "g12a" || "$SOCFAMILY" == "g12b" || "$SOCFAMILY" == "sm1" ]]
|
||||
then
|
||||
echo "${SOCFAMILY} is not supported - should be [g12a, g12b, sm1]"
|
||||
usage
|
||||
exit 22
|
||||
fi
|
||||
|
||||
BIN_LIST="$SOCFAMILY/bl2.bin \
|
||||
$SOCFAMILY/bl30.bin \
|
||||
$SOCFAMILY/bl31.bin \
|
||||
$SOCFAMILY/bl31.img \
|
||||
$SOCFAMILY/aml_encrypt_$SOCFAMILY "
|
||||
|
||||
FW_LIST="$SOCFAMILY/*.fw"
|
||||
|
||||
# path to clone the openlinux repos
|
||||
TMP_GIT=$(mktemp -d)
|
||||
|
||||
TMP="fip-collect-${SOCFAMILY}-${REFBOARD}-${GITBRANCH}-$(date +%Y%m%d-%H%M%S)"
|
||||
mkdir $TMP
|
||||
|
||||
# U-Boot
|
||||
git clone --depth=2 https://github.com/khadas/u-boot -b $GITBRANCH $TMP_GIT/u-boot
|
||||
|
||||
mkdir $TMP_GIT/gcc-linaro-aarch64-none-elf
|
||||
wget -qO- https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz | tar -xJ --strip-components=1 -C $TMP_GIT/gcc-linaro-aarch64-none-elf
|
||||
mkdir $TMP_GIT/gcc-linaro-arm-none-eabi
|
||||
wget -qO- https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz | tar -xJ --strip-components=1 -C $TMP_GIT/gcc-linaro-arm-none-eabi
|
||||
sed -i "s,/opt/gcc-.*/bin/,," $TMP_GIT/u-boot/Makefile
|
||||
(
|
||||
cd $TMP_GIT/u-boot
|
||||
make ${REFBOARD}_defconfig
|
||||
PATH=$TMP_GIT/gcc-linaro-aarch64-none-elf/bin:$TMP_GIT/gcc-linaro-arm-none-eabi/bin:$PATH CROSS_COMPILE=aarch64-none-elf- make -j8 > /dev/null
|
||||
cd fip/tools/ddr_parse && make clean && make
|
||||
)
|
||||
|
||||
cp $TMP_GIT/u-boot/build/board/khadas/*/firmware/acs.bin $TMP/
|
||||
cp $TMP_GIT/u-boot/build/scp_task/bl301.bin $TMP/
|
||||
# cp $TMP_GIT/u-boot/fip/tools/ddr_parse/parse $TMP/
|
||||
$TMP_GIT/u-boot/fip/tools/ddr_parse/parse ${TMP}/acs.bin
|
||||
# FIP/BLX
|
||||
echo $BIN_LIST
|
||||
for item in $BIN_LIST
|
||||
do
|
||||
BIN=$(echo $item)
|
||||
DIR1=$TMP_GIT/u-boot/$(basename --suffix=.bin $item)/bin/
|
||||
DIR2=$TMP_GIT/u-boot/$(basename --suffix=.img $item)_1.3/bin/
|
||||
DIR21=$TMP_GIT/u-boot/$(basename --suffix=.bin $item)_1.3/bin/
|
||||
DIR22=$TMP_GIT/u-boot/$(basename --suffix=.img $item)_1.3/bin/
|
||||
BRANCH=$GITBRANCH
|
||||
|
||||
if [[ -d $DIR1/$SOCFAMILY/ ]]
|
||||
then
|
||||
cp $DIR1/$BIN ${TMP}
|
||||
elif [[ -d $DIR2/$SOCFAMILY/ ]]
|
||||
then
|
||||
cp $DIR2/$BIN ${TMP}
|
||||
elif [[ -d $DIR21/$SOCFAMILY/ ]]
|
||||
then
|
||||
cp $DIR21/$BIN ${TMP}
|
||||
elif [[ -d $DIR22/$SOCFAMILY/ ]]
|
||||
then
|
||||
cp $DIR22/$BIN ${TMP}
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
echo $FW_LIST
|
||||
cp $TMP_GIT/u-boot/fip/$FW_LIST ${TMP}
|
||||
|
||||
|
||||
# Normalize
|
||||
mv $TMP_GIT/u-boot/fip/$SOCFAMILY/aml_encrypt_$SOCFAMILY $TMP/aml_encrypt
|
||||
|
||||
date > $TMP/info.txt
|
||||
echo "SOC: $SOCFAMILY" >> $TMP/info.txt
|
||||
echo "BRANCH: $GITBRANCH ($(date +%Y%m%d))" >> $TMP/info.txt
|
||||
for component in $TMP_GIT/*
|
||||
do
|
||||
if [[ -d $component/.git ]]
|
||||
then
|
||||
echo "$(basename $component): $(git --git-dir=$component/.git log --pretty=format:%H HEAD~1..HEAD)" >> $TMP/info.txt
|
||||
fi
|
||||
done
|
||||
echo "BOARD: $REFBOARD" >> $TMP/info.txt
|
||||
echo "export SOCFAMILY=$SOCFAMILY" > $TMP/soc-var.sh
|
||||
|
||||
rm -rf ${TMP_GIT}
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
#1 is the Amlogic fip directory
|
||||
#2 is u-boot directory
|
||||
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
set -o nounset
|
||||
|
||||
set -o xtrace
|
||||
|
||||
function fix_blx() {
|
||||
#bl2 file size 41K, bl21 file size 3K (file size not equal runtime size)
|
||||
#total 44K
|
||||
#after encrypt process, bl2 add 4K header, cut off 4K tail
|
||||
|
||||
#bl30 limit 41K
|
||||
#bl301 limit 12K
|
||||
#bl2 limit 41K
|
||||
#bl21 limit 3K, but encrypt tool need 48K bl2.bin, so fix to 7168byte.
|
||||
|
||||
declare blx_bin_limit=0
|
||||
declare blx01_bin_limit=0
|
||||
declare -i blx_size=0
|
||||
declare -i zero_size=0
|
||||
|
||||
#$7:name flag
|
||||
if [ "$7" = "bl30" ]; then
|
||||
if [ -e ${FIPDIR}/lpddr3_1d.fw -a "$SOCFAMILY" = "g12a" ]; then
|
||||
blx_bin_limit=47104 # VIM3L
|
||||
else
|
||||
blx_bin_limit=40960 # PD#132613 2016-10-31 update, 41984->40960
|
||||
fi
|
||||
blx01_bin_limit=13312 # PD#132613 2016-10-31 update, 12288->13312
|
||||
elif [ "$7" = "bl2" ]; then
|
||||
if [ "$SOCFAMILY" = "g12a" -o "$SOCFAMILY" = "sm1" -o "$SOCFAMILY" = "g12b" ]; then
|
||||
blx_bin_limit=57344
|
||||
blx01_bin_limit=4096
|
||||
else
|
||||
blx_bin_limit=41984
|
||||
blx01_bin_limit=7168
|
||||
fi
|
||||
else
|
||||
echo "blx_fix name flag not supported!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# blx_size: blx.bin size, zero_size: fill with zeros
|
||||
blx_size=`du -b $1 | awk '{print int($1)}'`
|
||||
zero_size=$blx_bin_limit-$blx_size
|
||||
dd if=/dev/zero of=$2 bs=1 count=$zero_size
|
||||
cat $1 $2 > $3
|
||||
rm $2
|
||||
|
||||
blx_size=`du -b $4 | awk '{print int($1)}'`
|
||||
zero_size=$blx01_bin_limit-$blx_size
|
||||
dd if=/dev/zero of=$2 bs=1 count=$zero_size
|
||||
cat $4 $2 > $5
|
||||
|
||||
cat $3 $5 > $6
|
||||
|
||||
rm $2
|
||||
}
|
||||
|
||||
FIPDIR=${1}
|
||||
UBOOTBIN=${2:-u-boot.bin}
|
||||
|
||||
source ${FIPDIR}/soc-var.sh
|
||||
|
||||
TMP=$(mktemp -d)
|
||||
|
||||
if [ "$SOCFAMILY" = "gxl" ]
|
||||
then
|
||||
|
||||
fix_blx ${FIPDIR}/bl30.bin ${TMP}/zero_tmp ${TMP}/bl30_zero.bin ${FIPDIR}/bl301.bin ${TMP}/bl301_zero.bin ${TMP}/bl30_new.bin bl30
|
||||
/usr/bin/env python2 ${FIPDIR}/acs_tool.pyc ${FIPDIR}/bl2.bin ${TMP}/bl2_acs.bin ${FIPDIR}/acs.bin 0
|
||||
fix_blx ${TMP}/bl2_acs.bin ${TMP}/zero_tmp ${TMP}/bl2_zero.bin ${FIPDIR}/bl21.bin ${TMP}/bl21_zero.bin ${TMP}/bl2_new.bin bl2
|
||||
${FIPDIR}/aml_encrypt --bl3enc --input ${TMP}/bl30_new.bin --output ${TMP}/bl30_new.bin.enc
|
||||
${FIPDIR}/aml_encrypt --bl3enc --input ${FIPDIR}/bl31.img --output ${TMP}/bl31.img.enc
|
||||
${FIPDIR}/aml_encrypt --bl3enc --input ${UBOOTBIN} --output ${TMP}/bl33.bin.enc
|
||||
${FIPDIR}/aml_encrypt --bl2sig --input ${TMP}/bl2_new.bin --output ${TMP}/bl2.n.bin.sig
|
||||
${FIPDIR}/aml_encrypt --bootmk --output ${TMP}/u-boot.bin \
|
||||
--bl2 ${TMP}/bl2.n.bin.sig \
|
||||
--bl30 ${TMP}/bl30_new.bin.enc \
|
||||
--bl31 ${TMP}/bl31.img.enc \
|
||||
--bl33 ${TMP}/bl33.bin.enc
|
||||
|
||||
elif [ "$SOCFAMILY" = "axg" ]
|
||||
then
|
||||
fix_blx ${FIPDIR}/bl30.bin ${TMP}/zero_tmp ${TMP}/bl30_zero.bin ${FIPDIR}/bl301.bin ${TMP}/bl301_zero.bin ${TMP}/bl30_new.bin bl30
|
||||
/usr/bin/env python2 ${FIPDIR}/acs_tool.pyc ${FIPDIR}/bl2.bin ${TMP}/bl2_acs.bin ${FIPDIR}/acs.bin 0
|
||||
fix_blx ${TMP}/bl2_acs.bin ${TMP}/zero_tmp ${TMP}/bl2_zero.bin ${FIPDIR}/bl21.bin ${TMP}/bl21_zero.bin ${TMP}/bl2_new.bin bl2
|
||||
${FIPDIR}/aml_encrypt --bl3sig --input ${TMP}/bl30_new.bin --output ${TMP}/bl30_new.bin.enc --level v3 --type bl30
|
||||
${FIPDIR}/aml_encrypt --bl3sig --input ${FIPDIR}/bl31.img --output ${TMP}/bl31.img.enc --level v3 --type bl31
|
||||
${FIPDIR}/aml_encrypt --bl3sig --input ${UBOOTBIN} --output ${TMP}/bl33.bin.enc --level v3 --type bl33 --compress lz4
|
||||
${FIPDIR}/aml_encrypt --bl2sig --input ${TMP}/bl2_new.bin --output ${TMP}/bl2.n.bin.sig
|
||||
${FIPDIR}/aml_encrypt --bootmk --output ${TMP}/u-boot.bin \
|
||||
--bl2 ${TMP}/bl2.n.bin.sig \
|
||||
--bl30 ${TMP}/bl30_new.bin.enc \
|
||||
--bl31 ${TMP}/bl31.img.enc \
|
||||
--bl33 ${TMP}/bl33.bin.enc \
|
||||
--level v3
|
||||
|
||||
elif [ "$SOCFAMILY" = "g12a" -o "$SOCFAMILY" = "sm1" -o "$SOCFAMILY" = "g12b" ]
|
||||
then
|
||||
cp ${FIPDIR}/acs.bin ${TMP}/acs.bin
|
||||
[ -e ${FIPDIR}/parse ] && ${FIPDIR}/parse ${TMP}/acs.bin
|
||||
fix_blx ${FIPDIR}/bl30.bin ${TMP}/zero_tmp ${TMP}/bl30_zero.bin ${FIPDIR}/bl301.bin ${TMP}/bl301_zero.bin ${TMP}/bl30_new.bin bl30
|
||||
fix_blx ${FIPDIR}/bl2.bin ${TMP}/zero_tmp ${TMP}/bl2_zero.bin ${TMP}/acs.bin ${TMP}/bl21_zero.bin ${TMP}/bl2_new.bin bl2
|
||||
${FIPDIR}/aml_encrypt --bl30sig --input ${TMP}/bl30_new.bin --output ${TMP}/bl30_new.bin.g12.enc --level v3
|
||||
${FIPDIR}/aml_encrypt --bl3sig --input ${TMP}/bl30_new.bin.g12.enc --output ${TMP}/bl30_new.bin.enc --level v3 --type bl30
|
||||
${FIPDIR}/aml_encrypt --bl3sig --input ${FIPDIR}/bl31.img --output ${TMP}/bl31.img.enc --level v3 --type bl31
|
||||
${FIPDIR}/aml_encrypt --bl3sig --input ${UBOOTBIN} --compress lz4 --output ${TMP}/bl33.bin.enc --level v3 --type bl33
|
||||
${FIPDIR}/aml_encrypt --bl2sig --input ${TMP}/bl2_new.bin --output ${TMP}/bl2.n.bin.sig
|
||||
if [ -e ${FIPDIR}/lpddr3_1d.fw ]
|
||||
then
|
||||
${FIPDIR}/aml_encrypt --bootmk --output ${TMP}/u-boot.bin \
|
||||
--bl2 ${TMP}/bl2.n.bin.sig \
|
||||
--bl30 ${TMP}/bl30_new.bin.enc \
|
||||
--bl31 ${TMP}/bl31.img.enc \
|
||||
--bl33 ${TMP}/bl33.bin.enc \
|
||||
--ddrfw1 ${FIPDIR}/ddr4_1d.fw \
|
||||
--ddrfw2 ${FIPDIR}/ddr4_2d.fw \
|
||||
--ddrfw3 ${FIPDIR}/ddr3_1d.fw \
|
||||
--ddrfw4 ${FIPDIR}/piei.fw \
|
||||
--ddrfw5 ${FIPDIR}/lpddr4_1d.fw \
|
||||
--ddrfw6 ${FIPDIR}/lpddr4_2d.fw \
|
||||
--ddrfw7 ${FIPDIR}/diag_lpddr4.fw \
|
||||
--ddrfw8 ${FIPDIR}/aml_ddr.fw \
|
||||
--ddrfw9 ${FIPDIR}/lpddr3_1d.fw \
|
||||
--level v3
|
||||
else
|
||||
${FIPDIR}/aml_encrypt --bootmk --output ${TMP}/u-boot.bin \
|
||||
--bl2 ${TMP}/bl2.n.bin.sig \
|
||||
--bl30 ${TMP}/bl30_new.bin.enc \
|
||||
--bl31 ${TMP}/bl31.img.enc \
|
||||
--bl33 ${TMP}/bl33.bin.enc \
|
||||
--ddrfw1 ${FIPDIR}/ddr4_1d.fw \
|
||||
--ddrfw2 ${FIPDIR}/ddr4_2d.fw \
|
||||
--ddrfw3 ${FIPDIR}/ddr3_1d.fw \
|
||||
--ddrfw4 ${FIPDIR}/piei.fw \
|
||||
--ddrfw5 ${FIPDIR}/lpddr4_1d.fw \
|
||||
--ddrfw6 ${FIPDIR}/lpddr4_2d.fw \
|
||||
--ddrfw7 ${FIPDIR}/diag_lpddr4.fw \
|
||||
--ddrfw8 ${FIPDIR}/aml_ddr.fw \
|
||||
--level v3
|
||||
fi
|
||||
else
|
||||
echo "${SOCFAMILY} is not supported - should be [gxl, axg, g12a, sm1, g12b]"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
TMP2="uboot-bins-$(date +%Y%m%d-%H%M%S)"
|
||||
mkdir $TMP2
|
||||
ln -sfn $TMP2 uboot-bins
|
||||
|
||||
mv ${TMP}/u-boot.bin{,.sd.bin,.usb.bl2,.usb.tpl} ${TMP2}
|
||||
rm -r ${TMP}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,54 @@
|
|||
# Use this file to generate dtb.img and dtbo.img instead of using
|
||||
# BOARD_PREBUILT_DTBIMAGE_DIR. We need to keep dtb and dtbo files at the fixed
|
||||
# positions in images, so that bootloader can rely on their indexes in the
|
||||
# image. As dtbo.img must be signed with AVB tool, we generate intermediate
|
||||
# dtbo.img, and the resulting $(PRODUCT_OUT)/dtbo.img will be created with
|
||||
# Android build system, by exploiting BOARD_PREBUILT_DTBOIMAGE variable.
|
||||
|
||||
ifneq ($(filter yukawa%, $(TARGET_DEVICE)),)
|
||||
|
||||
MKDTIMG := system/libufdt/utils/src/mkdtboimg.py
|
||||
DTBIMAGE := $(PRODUCT_OUT)/dtb.img
|
||||
DTBOIMAGE := $(PRODUCT_OUT)/$(DTBO_UNSIGNED)
|
||||
|
||||
# Please keep this list fixed: add new files in the end of the list
|
||||
DTB_FILES := \
|
||||
$(LOCAL_DTB)/meson-g12a-sei510.dtb \
|
||||
$(LOCAL_DTB)/meson-sm1-sei610.dtb \
|
||||
$(LOCAL_DTB)/meson-sm1-khadas-vim3l.dtb \
|
||||
$(LOCAL_DTB)/meson-g12b-a311d-khadas-vim3.dtb
|
||||
|
||||
# Please keep this list fixed: add new files in the end of the list
|
||||
DTBO_FILES := \
|
||||
$(LOCAL_DTB)/meson-g12a-sei510-android.dtb \
|
||||
$(LOCAL_DTB)/meson-sm1-sei610-android.dtb \
|
||||
$(LOCAL_DTB)/meson-sm1-khadas-vim3l-android.dtb \
|
||||
$(LOCAL_DTB)/meson-g12b-a311d-khadas-vim3-android.dtb \
|
||||
|
||||
$(DTBIMAGE): $(DTB_FILES)
|
||||
cat $^ > $@
|
||||
|
||||
$(DTBOIMAGE): PRIVATE_MKDTIMG := $(MKDTIMG)
|
||||
$(DTBOIMAGE): PRIVATE_DTBO_FILES := $(DTBO_FILES)
|
||||
$(DTBOIMAGE): $(DTBO_FILES) $(MKDTIMG)
|
||||
$(PRIVATE_MKDTIMG) create $@ $(PRIVATE_DTBO_FILES)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := dtbimage
|
||||
LOCAL_LICENSE_KINDS := legacy_restricted
|
||||
LOCAL_LICENSE_CONDITIONS := restricted
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(DTBIMAGE)
|
||||
include $(BUILD_PHONY_PACKAGE)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := dtboimage
|
||||
LOCAL_LICENSE_KINDS := legacy_restricted
|
||||
LOCAL_LICENSE_CONDITIONS := restricted
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(DTBOIMAGE)
|
||||
include $(BUILD_PHONY_PACKAGE)
|
||||
|
||||
droidcore: dtbimage dtboimage
|
||||
|
||||
$(call dist-for-goals, dist_files, $(DTBOIMAGE))
|
||||
|
||||
endif
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
<compatibility-matrix version="1.0" type="device">
|
||||
<hal format="hidl" optional="false">
|
||||
<name>android.frameworks.displayservice</name>
|
||||
<version>1.0</version>
|
||||
<interface>
|
||||
<name>IDisplayService</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="hidl" optional="false">
|
||||
<name>android.frameworks.sensorservice</name>
|
||||
<version>1.0</version>
|
||||
<interface>
|
||||
<name>ISensorManager</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="hidl" optional="false">
|
||||
<name>android.hidl.manager</name>
|
||||
<version>1.2</version>
|
||||
<interface>
|
||||
<name>IServiceManager</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="hidl" optional="true">
|
||||
<name>android.hidl.memory</name>
|
||||
<version>1.0</version>
|
||||
<interface>
|
||||
<name>IMapper</name>
|
||||
<instance>ashmem</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="hidl" optional="false">
|
||||
<name>android.hidl.token</name>
|
||||
<version>1.0</version>
|
||||
<interface>
|
||||
<name>ITokenManager</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="hidl" optional="false">
|
||||
<name>android.system.net.netd</name>
|
||||
<version>1.1</version>
|
||||
<interface>
|
||||
<name>INetd</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="hidl" optional="false">
|
||||
<name>android.system.wifi.keystore</name>
|
||||
<version>1.0</version>
|
||||
<interface>
|
||||
<name>IKeystore</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
</compatibility-matrix>
|
||||
|
|
@ -0,0 +1,385 @@
|
|||
PRODUCT_SOONG_NAMESPACES += device/amlogic/yukawa
|
||||
|
||||
ifeq ($(TARGET_PREBUILT_KERNEL),)
|
||||
LOCAL_KERNEL := device/amlogic/yukawa-kernel/$(TARGET_KERNEL_USE)/Image.lz4
|
||||
else
|
||||
LOCAL_KERNEL := $(TARGET_PREBUILT_KERNEL)
|
||||
endif
|
||||
|
||||
PRODUCT_COPY_FILES += $(LOCAL_KERNEL):kernel
|
||||
|
||||
# Build and run only ART
|
||||
PRODUCT_RUNTIMES := runtime_libart_default
|
||||
|
||||
# Enable updating of APEXes
|
||||
$(call inherit-product, $(SRC_TARGET_DIR)/product/updatable_apex.mk)
|
||||
|
||||
# Enable Scoped Storage related
|
||||
$(call inherit-product, $(SRC_TARGET_DIR)/product/emulated_storage.mk)
|
||||
|
||||
DEVICE_PACKAGE_OVERLAYS := device/amlogic/yukawa/overlay
|
||||
ifeq ($(TARGET_USE_TABLET_LAUNCHER), true)
|
||||
# Setup tablet build
|
||||
$(call inherit-product, frameworks/native/build/tablet-10in-xhdpi-2048-dalvik-heap.mk)
|
||||
$(call inherit-product, $(SRC_TARGET_DIR)/product/full_base.mk)
|
||||
else
|
||||
# Setup TV Build
|
||||
USE_OEM_TV_APP := true
|
||||
$(call inherit-product, device/google/atv/products/atv_base.mk)
|
||||
PRODUCT_CHARACTERISTICS := tv
|
||||
PRODUCT_AAPT_PREF_CONFIG := tvdpi
|
||||
PRODUCT_IS_ATV := true
|
||||
endif
|
||||
|
||||
PRODUCT_PACKAGES += llkd
|
||||
|
||||
ifeq ($(TARGET_USE_AB_SLOT), true)
|
||||
# A/B support
|
||||
PRODUCT_PACKAGES += \
|
||||
otapreopt_script \
|
||||
cppreopts.sh \
|
||||
update_engine \
|
||||
update_verifier
|
||||
AB_OTA_POSTINSTALL_CONFIG += \
|
||||
RUN_POSTINSTALm=true \
|
||||
POSTINSTALL_PATH=system/bin/otapreopt_script \
|
||||
FILESYSTEM_TYPE=ext4 \
|
||||
POSTINSTALL_OPTIONAL=true
|
||||
|
||||
PRODUCT_PACKAGES += \
|
||||
update_engine_sideload \
|
||||
sg_write_buffer \
|
||||
f2fs_io
|
||||
|
||||
# The following modules are included in debuggable builds only.
|
||||
PRODUCT_PACKAGES_DEBUG += \
|
||||
bootctl \
|
||||
update_engine_client
|
||||
|
||||
# Write flags to the vendor space in /misc partition.
|
||||
PRODUCT_PACKAGES += \
|
||||
misc_writer
|
||||
|
||||
PRODUCT_PACKAGES += \
|
||||
fs_config_dirs \
|
||||
fs_config_files
|
||||
|
||||
# Boot control
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.boot@1.2-impl \
|
||||
android.hardware.boot@1.2-impl.recovery \
|
||||
android.hardware.boot@1.2-service \
|
||||
bootctrl.yukawa.recovery \
|
||||
bootctrl.yukawa
|
||||
endif
|
||||
|
||||
# Dynamic partitions
|
||||
PRODUCT_BUILD_SUPER_PARTITION := true
|
||||
PRODUCT_USE_DYNAMIC_PARTITIONS := true
|
||||
PRODUCT_USE_DYNAMIC_PARTITION_SIZE := true
|
||||
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.fastboot@1.0 \
|
||||
android.hardware.fastboot@1.0-impl-mock \
|
||||
fastbootd
|
||||
|
||||
# All VNDK libraries (HAL interfaces, VNDK, VNDK-SP, LL-NDK)
|
||||
PRODUCT_PACKAGES += vndk_package
|
||||
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.health@2.1-impl-cuttlefish \
|
||||
android.hardware.health@2.1-service
|
||||
|
||||
ifeq ($(TARGET_USE_AB_SLOT), true)
|
||||
ifeq ($(TARGET_AVB_ENABLE), true)
|
||||
PRODUCT_COPY_FILES += \
|
||||
$(LOCAL_PATH)/fstab.yukawa.avb.ab:$(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk/fstab.yukawa \
|
||||
$(LOCAL_PATH)/fstab.yukawa.avb.ab:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.yukawa
|
||||
else
|
||||
PRODUCT_COPY_FILES += \
|
||||
$(LOCAL_PATH)/fstab.yukawa.ab:$(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk/fstab.yukawa \
|
||||
$(LOCAL_PATH)/fstab.yukawa.ab:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.yukawa
|
||||
endif
|
||||
else
|
||||
ifeq ($(TARGET_AVB_ENABLE), true)
|
||||
PRODUCT_COPY_FILES += \
|
||||
$(LOCAL_PATH)/fstab.ramdisk.common.avb:$(TARGET_COPY_OUT_RAMDISK)/fstab.yukawa \
|
||||
$(LOCAL_PATH)/fstab.yukawa:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.yukawa
|
||||
else
|
||||
PRODUCT_COPY_FILES += \
|
||||
$(LOCAL_PATH)/fstab.ramdisk.common:$(TARGET_COPY_OUT_RAMDISK)/fstab.yukawa \
|
||||
$(LOCAL_PATH)/fstab.yukawa:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.yukawa
|
||||
endif
|
||||
endif
|
||||
|
||||
PRODUCT_COPY_FILES += \
|
||||
$(LOCAL_PATH)/init.yukawa.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/hw/init.yukawa.rc \
|
||||
$(LOCAL_PATH)/init.yukawa.usb.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/hw/init.yukawa.usb.rc \
|
||||
$(LOCAL_PATH)/init.recovery.hardware.rc:recovery/root/init.recovery.yukawa.rc \
|
||||
$(LOCAL_PATH)/ueventd.rc:$(TARGET_COPY_OUT_VENDOR)/ueventd.rc \
|
||||
$(LOCAL_PATH)/wifi/wpa_supplicant.conf:$(TARGET_COPY_OUT_VENDOR)/etc/wifi/wpa_supplicant.conf \
|
||||
$(LOCAL_PATH)/wifi/wpa_supplicant_overlay.conf:$(TARGET_COPY_OUT_VENDOR)/etc/wifi/wpa_supplicant_overlay.conf \
|
||||
$(LOCAL_PATH)/wifi/p2p_supplicant_overlay.conf:$(TARGET_COPY_OUT_VENDOR)/etc/wifi/p2p_supplicant_overlay.conf
|
||||
|
||||
# BT and Wifi FW
|
||||
PRODUCT_COPY_FILES += \
|
||||
$(LOCAL_PATH)/binaries/bt-wifi-firmware/BCM.hcd:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/BCM4359C0.hcd \
|
||||
$(LOCAL_PATH)/binaries/bt-wifi-firmware/fw_bcm4359c0_ag.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/fw_bcm4359c0_ag.bin \
|
||||
$(LOCAL_PATH)/binaries/bt-wifi-firmware/nvram_ap6359.txt:$(TARGET_COPY_OUT_VENDOR)/firmware/brcm/nvram.txt
|
||||
|
||||
ifeq ($(TARGET_USE_TABLET_LAUNCHER), true)
|
||||
# Use Launcher3QuickStep
|
||||
PRODUCT_PACKAGES += Launcher3QuickStep
|
||||
else
|
||||
ifeq ($(TARGET_USE_SAMPLE_LAUNCHER), true)
|
||||
PRODUCT_PACKAGES += \
|
||||
TvSampleLeanbackLauncher
|
||||
endif
|
||||
|
||||
# TV Specific Packages
|
||||
PRODUCT_PACKAGES += \
|
||||
LiveTv \
|
||||
google-tv-pairing-protocol \
|
||||
LeanbackSampleApp \
|
||||
tv_input.default \
|
||||
com.android.media.tv.remoteprovider \
|
||||
InputDevices
|
||||
|
||||
PRODUCT_PACKAGES += \
|
||||
LeanbackIME
|
||||
|
||||
ifeq (,$(filter $(TARGET_PRODUCT),yukawa_gms yukawa32_gms yukawa_sei510_gms))
|
||||
PRODUCT_PACKAGES += \
|
||||
TvProvision \
|
||||
TVLauncherNoGms \
|
||||
TVRecommendationsNoGms
|
||||
endif
|
||||
endif
|
||||
|
||||
PRODUCT_PACKAGES += \
|
||||
libhidltransport \
|
||||
libhwbinder
|
||||
|
||||
PRODUCT_PROPERTY_OVERRIDES += ro.sf.lcd_density=320
|
||||
|
||||
PRODUCT_PACKAGES += libGLES_mali
|
||||
PRODUCT_PACKAGES += libGLES_android
|
||||
|
||||
# Vulkan
|
||||
PRODUCT_COPY_FILES += \
|
||||
frameworks/native/data/etc/android.hardware.vulkan.version-1_1.xml:vendor/etc/permissions/android.hardware.vulkan.version.xml \
|
||||
frameworks/native/data/etc/android.hardware.vulkan.compute-0.xml:vendor/etc/permissions/android.hardware.vulkan.compute.xml \
|
||||
frameworks/native/data/etc/android.hardware.vulkan.level-1.xml:vendor/etc/permissions/android.hardware.vulkan.level.xml
|
||||
|
||||
PRODUCT_PACKAGES += vulkan.yukawa.so
|
||||
|
||||
# Bluetooth
|
||||
PRODUCT_PACKAGES += android.hardware.bluetooth@1.1-service.btlinux
|
||||
PRODUCT_PROPERTY_OVERRIDES += \
|
||||
bluetooth.core.gap.le.privacy.enabled=false \
|
||||
bluetooth.profile.asha.central.enabled=true \
|
||||
bluetooth.profile.a2dp.source.enabled=true \
|
||||
bluetooth.profile.avrcp.target.enabled=true \
|
||||
bluetooth.profile.bap.broadcast.assist.enabled=true \
|
||||
bluetooth.profile.bap.unicast.client.enabled=true \
|
||||
bluetooth.profile.bas.client.enabled=true \
|
||||
bluetooth.profile.ccp.server.enabled=true \
|
||||
bluetooth.profile.csip.set_coordinator.enabled=true \
|
||||
bluetooth.profile.gatt.enabled=true \
|
||||
bluetooth.profile.hap.client.enabled=true \
|
||||
bluetooth.profile.hfp.ag.enabled=true \
|
||||
bluetooth.profile.hid.host.enabled=true \
|
||||
bluetooth.profile.mcp.server.enabled=true \
|
||||
bluetooth.profile.opp.enabled=true \
|
||||
bluetooth.profile.pan.nap.enabled=true \
|
||||
bluetooth.profile.pan.panu.enabled=true \
|
||||
bluetooth.profile.vcp.controller.enabled=true
|
||||
|
||||
# Wifi
|
||||
PRODUCT_PACKAGES += libwpa_client wpa_supplicant hostapd wificond wpa_cli
|
||||
PRODUCT_PROPERTY_OVERRIDES += wifi.interface=wlan0 \
|
||||
wifi.supplicant_scan_interval=15
|
||||
|
||||
# Build default bluetooth a2dp and usb audio HALs
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.bluetooth.audio@2.0-impl \
|
||||
audio.usb.default \
|
||||
audio.primary.yukawa \
|
||||
audio.r_submix.default \
|
||||
audio.bluetooth.default \
|
||||
tinyplay \
|
||||
tinycap \
|
||||
tinymix \
|
||||
tinypcminfo \
|
||||
cplay
|
||||
|
||||
# Video
|
||||
PRODUCT_COPY_FILES += \
|
||||
$(LOCAL_PATH)/binaries/video_firmware/g12a_h264.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/meson/vdec/g12a_h264.bin \
|
||||
$(LOCAL_PATH)/binaries/video_firmware/g12a_hevc_mmu.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/meson/vdec/g12a_hevc_mmu.bin \
|
||||
$(LOCAL_PATH)/binaries/video_firmware/g12a_vp9.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/meson/vdec/g12a_vp9.bin \
|
||||
$(LOCAL_PATH)/binaries/video_firmware/gxl_mpeg4_5.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/meson/vdec/gxl_mpeg4_5.bin \
|
||||
$(LOCAL_PATH)/binaries/video_firmware/gxl_mpeg12.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/meson/vdec/gxl_mpeg12.bin \
|
||||
$(LOCAL_PATH)/binaries/video_firmware/gxl_mjpeg.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/meson/vdec/gxl_mjpeg.bin \
|
||||
$(LOCAL_PATH)/binaries/video_firmware/sm1_hevc_mmu.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/meson/vdec/sm1_hevc_mmu.bin \
|
||||
$(LOCAL_PATH)/binaries/video_firmware/sm1_vp9_mmu.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/meson/vdec/sm1_vp9_mmu.bin
|
||||
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.audio.service \
|
||||
android.hardware.audio@7.0-impl \
|
||||
android.hardware.audio.effect@7.0-impl \
|
||||
android.hardware.soundtrigger@2.3-impl \
|
||||
|
||||
# Hardware Composer HAL
|
||||
#
|
||||
PRODUCT_PACKAGES += \
|
||||
hwcomposer.drm_meson \
|
||||
android.hardware.drm-service.widevine \
|
||||
android.hardware.drm-service.clearkey
|
||||
|
||||
# CEC
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.tv.cec@1.0-impl \
|
||||
android.hardware.tv.cec@1.0-service \
|
||||
hdmi_cec.yukawa
|
||||
|
||||
PRODUCT_PROPERTY_OVERRIDES += ro.hdmi.device_type=4 \
|
||||
persist.sys.hdmi.keep_awake=false
|
||||
|
||||
PRODUCT_COPY_FILES += \
|
||||
$(LOCAL_PATH)/input/Generic.kl:$(TARGET_COPY_OUT_VENDOR)/usr/keylayout/Generic.kl \
|
||||
frameworks/native/data/etc/android.hardware.hdmi.cec.xml:system/etc/permissions/android.hardware.hdmi.cec.xml
|
||||
|
||||
PRODUCT_PACKAGES += \
|
||||
gralloc.yukawa \
|
||||
android.hardware.graphics.composer@2.2-impl \
|
||||
android.hardware.graphics.composer@2.2-service \
|
||||
android.hardware.graphics.allocator@2.0-service \
|
||||
android.hardware.graphics.allocator@2.0-impl \
|
||||
android.hardware.graphics.mapper@2.0-impl-2.1
|
||||
|
||||
# PowerHAL
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.power-service.example
|
||||
|
||||
# PowerStats HAL
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.power.stats-service.example
|
||||
|
||||
# Sensor HAL
|
||||
ifneq ($(TARGET_SENSOR_MEZZANINE),)
|
||||
TARGET_USES_NANOHUB_SENSORHAL := true
|
||||
NANOHUB_SENSORHAL_LID_STATE_ENABLED := true
|
||||
NANOHUB_SENSORHAL_SENSORLIST := $(LOCAL_PATH)/sensorhal/sensorlist_$(TARGET_SENSOR_MEZZANINE).cpp
|
||||
NANOHUB_SENSORHAL_DIRECT_REPORT_ENABLED := true
|
||||
NANOHUB_SENSORHAL_DYNAMIC_SENSOR_EXT_ENABLED := true
|
||||
|
||||
PRODUCT_PACKAGES += \
|
||||
context_hub.default \
|
||||
sensors.yukawa \
|
||||
android.hardware.sensors@1.0-service \
|
||||
android.hardware.sensors@1.0-impl \
|
||||
android.hardware.contexthub@1.2-service \
|
||||
android.hardware.contexthub@1.2-impl
|
||||
|
||||
# Nanohub tools
|
||||
PRODUCT_PACKAGES += stm32_flash nanoapp_cmd nanotool
|
||||
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/amlogic/yukawa/init.common.nanohub.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.nanohub.rc
|
||||
|
||||
# Copy sensors config file(s)
|
||||
PRODUCT_COPY_FILES += \
|
||||
frameworks/native/data/etc/android.hardware.sensor.accelerometer.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.accelerometer.xml \
|
||||
frameworks/native/data/etc/android.hardware.sensor.ambient_temperature.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.ambient_temperature.xml \
|
||||
frameworks/native/data/etc/android.hardware.sensor.barometer.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.barometer.xml \
|
||||
frameworks/native/data/etc/android.hardware.sensor.compass.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.compass.xml \
|
||||
frameworks/native/data/etc/android.hardware.sensor.gyroscope.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.gyroscope.xml \
|
||||
frameworks/native/data/etc/android.hardware.sensor.hifi_sensors.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.hifi_sensors.xml \
|
||||
frameworks/native/data/etc/android.hardware.sensor.light.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.light.xml \
|
||||
frameworks/native/data/etc/android.hardware.sensor.relative_humidity.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.relative_humidity.xml \
|
||||
frameworks/native/data/etc/android.hardware.sensor.stepcounter.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.stepcounter.xml \
|
||||
frameworks/native/data/etc/android.hardware.sensor.stepdetector.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.stepdetector.xml
|
||||
|
||||
# Argonkey VL53L0X proximity driver is not available yet. So we are going to copy conf file for neonkey only
|
||||
ifeq ($(TARGET_SENSOR_MEZZANINE),neonkey)
|
||||
PRODUCT_COPY_FILES += \
|
||||
frameworks/native/data/etc/android.hardware.sensor.proximity.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.proximity.xml
|
||||
endif
|
||||
endif
|
||||
|
||||
# Software Gatekeeper HAL
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.gatekeeper@1.0-service.software
|
||||
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.keymaster@3.0-impl \
|
||||
android.hardware.keymaster@3.0-service
|
||||
|
||||
# USB
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.usb@1.1-service
|
||||
|
||||
PRODUCT_COPY_FILES += \
|
||||
frameworks/native/data/etc/android.software.app_widgets.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.app_widgets.xml \
|
||||
frameworks/native/data/etc/android.hardware.ethernet.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.ethernet.xml \
|
||||
frameworks/native/data/etc/android.hardware.usb.accessory.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.usb.accessory.xml \
|
||||
frameworks/native/data/etc/android.hardware.usb.host.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.usb.host.xml \
|
||||
frameworks/native/data/etc/android.software.device_admin.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.device_admin.xml \
|
||||
frameworks/native/data/etc/android.hardware.wifi.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.wifi.xml \
|
||||
frameworks/native/data/etc/android.hardware.wifi.direct.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.wifi.direct.xml \
|
||||
frameworks/native/data/etc/android.hardware.bluetooth.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.bluetooth.xml \
|
||||
frameworks/native/data/etc/android.hardware.bluetooth_le.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.bluetooth_le.xml \
|
||||
frameworks/native/data/etc/android.software.cts.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.cts.xml \
|
||||
frameworks/native/data/etc/android.software.backup.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.backup.xml
|
||||
|
||||
# audio policy configuration
|
||||
USE_XML_AUDIO_POLICY_CONF := 1
|
||||
PRODUCT_COPY_FILES += \
|
||||
frameworks/av/services/audiopolicy/config/a2dp_in_audio_policy_configuration_7_0.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_in_audio_policy_configuration_7_0.xml \
|
||||
frameworks/av/services/audiopolicy/config/bluetooth_audio_policy_configuration_7_0.xml:$(TARGET_COPY_OUT_VENDOR)/etc/bluetooth_audio_policy_configuration_7_0.xml \
|
||||
frameworks/av/services/audiopolicy/config/r_submix_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/r_submix_audio_policy_configuration.xml \
|
||||
frameworks/av/services/audiopolicy/config/usb_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/usb_audio_policy_configuration.xml \
|
||||
frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
|
||||
frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml \
|
||||
frameworks/av/media/libeffects/data/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml
|
||||
|
||||
AUDIO_DEFAULT_OUTPUT ?= speaker
|
||||
ifeq ($(AUDIO_DEFAULT_OUTPUT),hdmi)
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/amlogic/yukawa/hal/audio/mixer_paths_hdmi_only.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
|
||||
device/amlogic/yukawa/hal/audio/audio_policy_configuration_hdmi_only.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml
|
||||
DEVICE_PACKAGE_OVERLAYS += \
|
||||
device/amlogic/yukawa/hal/audio/overlay_hdmi_only
|
||||
TARGET_USE_HDMI_AUDIO ?= true
|
||||
else
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/amlogic/yukawa/hal/audio/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
|
||||
device/amlogic/yukawa/hal/audio/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml
|
||||
endif
|
||||
|
||||
# Copy media codecs config file
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/amlogic/yukawa/media_xml/media_codecs.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs.xml \
|
||||
device/amlogic/yukawa/media_xml/media_profiles.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_profiles_V1_0.xml \
|
||||
frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_google_audio.xml
|
||||
|
||||
# Enable BT Pairing with button BTN_0 (key 256)
|
||||
PRODUCT_PACKAGES += YukawaService YukawaAndroidOverlay
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/amlogic/yukawa/input/Vendor_0001_Product_0001.kl:$(TARGET_COPY_OUT_VENDOR)/usr/keylayout/Vendor_0001_Product_0001.kl
|
||||
|
||||
|
||||
# Light HAL
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.light-service \
|
||||
lights-yukawa
|
||||
|
||||
# Enable USB Camera
|
||||
PRODUCT_PACKAGES += android.hardware.camera.provider@2.4-impl
|
||||
PRODUCT_PACKAGES += android.hardware.camera.provider@2.4-external-service
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/amlogic/yukawa/hal/camera/external_camera_config.xml:$(TARGET_COPY_OUT_VENDOR)/etc/external_camera_config.xml
|
||||
|
||||
# Include Virtualization APEX
|
||||
$(call inherit-product, packages/modules/Virtualization/apex/product_packages.mk)
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
ifndef TARGET_KERNEL_USE
|
||||
TARGET_KERNEL_USE := 5.10
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_VIM3), true)
|
||||
TARGET_DEV_BOARD := vim3
|
||||
else ifeq ($(TARGET_VIM3L), true)
|
||||
TARGET_DEV_BOARD := vim3l
|
||||
else ifeq ($(TARGET_DEV_BOARD),)
|
||||
TARGET_DEV_BOARD := sei610
|
||||
endif
|
||||
|
||||
ifneq ($(filter $(TARGET_DEV_BOARD),vim3),)
|
||||
AUDIO_DEFAULT_OUTPUT := hdmi
|
||||
GPU_TYPE := gondul_ion
|
||||
else ifneq ($(filter $(TARGET_DEV_BOARD),vim3l),)
|
||||
AUDIO_DEFAULT_OUTPUT := hdmi
|
||||
endif
|
||||
|
||||
$(call inherit-product, device/amlogic/yukawa/device-common.mk)
|
||||
|
||||
PRODUCT_PROPERTY_OVERRIDES += ro.product.device=$(TARGET_DEV_BOARD)
|
||||
GPU_TYPE ?= dvalin_ion
|
||||
|
||||
BOARD_KERNEL_DTB := device/amlogic/yukawa-kernel/$(TARGET_KERNEL_USE)
|
||||
|
||||
ifeq ($(TARGET_PREBUILT_DTB),)
|
||||
LOCAL_DTB := $(BOARD_KERNEL_DTB)
|
||||
else
|
||||
LOCAL_DTB := $(TARGET_PREBUILT_DTB)
|
||||
endif
|
||||
|
||||
# Feature permissions
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/amlogic/yukawa/permissions/yukawa.xml:/system/etc/sysconfig/yukawa.xml
|
||||
|
||||
# Speaker EQ
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/amlogic/yukawa/hal/audio/speaker_eq_sei610.fir:$(TARGET_COPY_OUT_VENDOR)/etc/speaker_eq_sei610.fir
|
||||
|
||||
# Hotword Mic Toggle Provider
|
||||
ifneq ($(filter $(TARGET_DEV_BOARD),sei610),)
|
||||
PRODUCT_PACKAGES += \
|
||||
YukawaHotwordMicToggleProvider
|
||||
endif
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
ifndef TARGET_KERNEL_USE
|
||||
TARGET_KERNEL_USE=5.10
|
||||
endif
|
||||
|
||||
$(call inherit-product, device/amlogic/yukawa/device-common.mk)
|
||||
|
||||
PRODUCT_PROPERTY_OVERRIDES += ro.product.device=sei510
|
||||
|
||||
GPU_TYPE ?= dvalin_ion
|
||||
|
||||
BOARD_KERNEL_DTB := device/amlogic/yukawa-kernel/$(TARGET_KERNEL_USE)
|
||||
|
||||
ifeq ($(TARGET_PREBUILT_DTB),)
|
||||
LOCAL_DTB := $(BOARD_KERNEL_DTB)
|
||||
else
|
||||
LOCAL_DTB := $(TARGET_PREBUILT_DTB)
|
||||
endif
|
||||
|
||||
# Feature permissions
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/amlogic/yukawa/permissions/yukawa.xml:/system/etc/sysconfig/yukawa.xml
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
system /system ext4 noatime,ro,errors=panic wait,logical,first_stage_mount
|
||||
vendor /vendor ext4 noatime,ro,errors=panic wait,logical,first_stage_mount
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
system /system ext4 noatime,ro,errors=panic wait,avb=vbmeta,logical,first_stage_mount
|
||||
vendor /vendor ext4 noatime,ro,errors=panic wait,avb,logical,first_stage_mount
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
system /system ext4 noatime,ro,errors=panic wait,logical,first_stage_mount
|
||||
vendor /vendor ext4 noatime,ro,errors=panic wait,logical,first_stage_mount
|
||||
/dev/block/platform/soc/ffe07000.mmc/by-name/userdata /data f2fs noatime,nosuid,nodev latemount,wait,check,quota,fileencryption=software,quota
|
||||
/dev/block/platform/soc/ffe07000.mmc/by-name/userdata /data ext4 noatime,nosuid,nodev,nodelalloc,nomblk_io_submit,errors=panic latemount,wait,check,quota,formattable,reservedsize=32M
|
||||
/dev/block/platform/soc/ffe07000.mmc/by-name/cache /cache ext4 noatime,nosuid,nodev,nodelalloc,nomblk_io_submit,errors=panic latemount,wait,check,formattable
|
||||
/dev/block/platform/soc/ffe07000.mmc/by-name/misc /misc emmc defaults defaults
|
||||
/dev/block/platform/soc/ffe07000.mmc/by-name/recovery /recovery emmc defaults defaults
|
||||
/dev/block/platform/soc/ffe07000.mmc/by-name/boot /boot emmc defaults defaults
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
system /system ext4 noatime,ro,errors=panic wait,avb=vbmeta,logical,first_stage_mount
|
||||
vendor /vendor ext4 noatime,ro,errors=panic wait,avb,logical,first_stage_mount
|
||||
/dev/block/platform/soc/ffe07000.mmc/by-name/userdata /data f2fs noatime,nosuid,nodev latemount,wait,check,quota,fileencryption=software,quota
|
||||
/dev/block/platform/soc/ffe07000.mmc/by-name/userdata /data ext4 noatime,nosuid,nodev,nodelalloc,nomblk_io_submit,errors=panic latemount,wait,check,quota,formattable,reservedsize=32M
|
||||
/dev/block/platform/soc/ffe07000.mmc/by-name/cache /cache ext4 noatime,nosuid,nodev,nodelalloc,nomblk_io_submit,errors=panic latemount,wait,check,formattable
|
||||
/dev/block/platform/soc/ffe07000.mmc/by-name/misc /misc emmc defaults defaults
|
||||
/dev/block/platform/soc/ffe07000.mmc/by-name/recovery /recovery emmc defaults defaults
|
||||
/dev/block/platform/soc/ffe07000.mmc/by-name/boot /boot emmc defaults defaults
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/dev/block/platform/soc/ffe07000.mmc/by-name/userdata /data f2fs noatime,nosuid,nodev latemount,wait,check,quota,fileencryption=software,quota
|
||||
/dev/block/platform/soc/ffe07000.mmc/by-name/userdata /data ext4 noatime,nosuid,nodev,nodelalloc,nomblk_io_submit,errors=panic latemount,wait,check,quota,formattable,reservedsize=32M
|
||||
/dev/block/platform/soc/ffe07000.mmc/by-name/cache /cache ext4 noatime,nosuid,nodev,nodelalloc,nomblk_io_submit,errors=panic latemount,wait,check,formattable
|
||||
/dev/block/platform/soc/ffe07000.mmc/by-name/misc /misc emmc defaults defaults
|
||||
system /system ext4 ro,barrier=1 wait,logical,first_stage_mount
|
||||
vendor /vendor ext4 ro,barrier=1 wait,logical,first_stage_mount
|
||||
*/block/mmcblk0 auto auto defaults voldmanaged=sdcard1:auto,encryptable=userdata
|
||||
*/block/sd* auto auto defaults voldmanaged=usb:auto,noemulatedsd
|
||||
/dev/block/zram0 none swap defaults zramsize=268435456
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
system /system ext4 noatime,ro,errors=panic wait,slotselect,logical,first_stage_mount
|
||||
vendor /vendor ext4 noatime,ro,errors=panic wait,slotselect,logical,first_stage_mount
|
||||
/dev/block/by-name/userdata /data f2fs noatime,nosuid,nodev latemount,wait,check,quota,fileencryption=software,quota
|
||||
/dev/block//by-name/userdata /data ext4 noatime,nosuid,nodev,nodelalloc,nomblk_io_submit,errors=panic latemount,wait,check,quota,formattable,reservedsize=32M
|
||||
/dev/block/by-name/misc /misc emmc defaults defaults
|
||||
*/block/mmcblk0 auto auto defaults voldmanaged=sdcard1:auto,encryptable=userdata
|
||||
*/block/sd* auto auto defaults voldmanaged=usb:auto,noemulatedsd
|
||||
/dev/block/zram0 none swap defaults zramsize=268435456
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
system /system ext4 noatime,ro,errors=panic wait,slotselect,avb=vbmeta,logical,first_stage_mount
|
||||
vendor /vendor ext4 noatime,ro,errors=panic wait,slotselect,avb,logical,first_stage_mount
|
||||
/dev/block/by-name/userdata /data f2fs noatime,nosuid,nodev latemount,wait,check,quota,fileencryption=software,quota
|
||||
/dev/block//by-name/userdata /data ext4 noatime,nosuid,nodev,nodelalloc,nomblk_io_submit,errors=panic latemount,wait,check,quota,formattable,reservedsize=32M
|
||||
/dev/block/by-name/misc /misc emmc defaults defaults
|
||||
*/block/mmcblk0 auto auto defaults voldmanaged=sdcard1:auto,encryptable=userdata
|
||||
*/block/sd* auto auto defaults voldmanaged=usb:auto,noemulatedsd
|
||||
/dev/block/zram0 none swap defaults zramsize=268435456
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#
|
||||
# Copyright 2017 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)
|
||||
include $(call all-makefiles-under,$(LOCAL_PATH))
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) 2016 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 audio HAL module, which is a stub, that 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 audio.<type>.<hardware/etc>.so where the only
|
||||
# required type is 'primary'. Other possibilites are 'a2dp', 'usb', etc.
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_HEADER_LIBRARIES += libhardware_headers
|
||||
LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)
|
||||
LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
|
||||
LOCAL_LICENSE_CONDITIONS := notice
|
||||
LOCAL_MODULE_RELATIVE_PATH := hw
|
||||
LOCAL_VENDOR_MODULE := true
|
||||
|
||||
LOCAL_SRC_FILES := audio_hw.c \
|
||||
audio_aec.c \
|
||||
fifo_wrapper.cpp \
|
||||
fir_filter.c
|
||||
LOCAL_SHARED_LIBRARIES := liblog libcutils libtinyalsa libaudioroute libaudioutils
|
||||
LOCAL_CFLAGS := -Wno-unused-parameter
|
||||
LOCAL_C_INCLUDES += \
|
||||
external/tinyalsa/include \
|
||||
external/expat/lib \
|
||||
$(call include-path-for, audio-route) \
|
||||
system/media/audio_utils/include \
|
||||
system/media/audio_effects/include
|
||||
|
||||
ifeq ($(TARGET_USE_HDMI_AUDIO),true)
|
||||
LOCAL_CFLAGS += -DUSE_HDMI_AUDIO
|
||||
endif
|
||||
ifneq ($(findstring google_aec, $(call all-makefiles-under,$(TOPDIR)vendor/amlogic/yukawa)),)
|
||||
LOCAL_SHARED_LIBRARIES += google_aec
|
||||
LOCAL_CFLAGS += -DAEC_HAL
|
||||
endif
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
|
@ -0,0 +1,708 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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.
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
/*
|
||||
* Typical AEC signal flow:
|
||||
*
|
||||
* Microphone Audio
|
||||
* Timestamps
|
||||
* +--------------------------------------+
|
||||
* | | +---------------+
|
||||
* | Microphone +---------------+ | | |
|
||||
* O|====== | Audio | Sample Rate | +-------> |
|
||||
* (from . +--+ Samples | + | | |
|
||||
* mic . +==================> Format |==============> |
|
||||
* codec) . | Conversion | | | Cleaned
|
||||
* O|====== | (if required) | | Acoustic | Audio
|
||||
* +---------------+ | Echo | Samples
|
||||
* | Canceller |===================>
|
||||
* | (AEC) |
|
||||
* Reference +---------------+ | |
|
||||
* Audio | Sample Rate | | |
|
||||
* Samples | + | | |
|
||||
* +=============> Format |==============> |
|
||||
* | | Conversion | | |
|
||||
* | | (if required) | +-------> |
|
||||
* | +---------------+ | | |
|
||||
* | | +---------------+
|
||||
* | +-------------------------------+
|
||||
* | | Reference Audio
|
||||
* | | Timestamps
|
||||
* | |
|
||||
* +--+----+---------+ AUDIO CAPTURE
|
||||
* | Speaker |
|
||||
* +------------+ Audio/Timestamp +---------------------------------------------------------------------------+
|
||||
* | Buffer |
|
||||
* +--^----^---------+ AUDIO PLAYBACK
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* |\ | |
|
||||
* | +-+ | |
|
||||
* (to | | +-----C----+
|
||||
* speaker | | | | Playback
|
||||
* codec) | | <=====+================================================================+ Audio
|
||||
* | +-+ Samples
|
||||
* |/
|
||||
*
|
||||
*/
|
||||
// clang-format on
|
||||
|
||||
#define LOG_TAG "audio_hw_aec"
|
||||
// #define LOG_NDEBUG 0
|
||||
|
||||
#include <audio_utils/primitives.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <sys/time.h>
|
||||
#include <tinyalsa/asoundlib.h>
|
||||
#include <unistd.h>
|
||||
#include <log/log.h>
|
||||
#include "audio_aec.h"
|
||||
|
||||
#ifdef AEC_HAL
|
||||
#include "audio_aec_process.h"
|
||||
#else
|
||||
#define aec_spk_mic_init(...) ((int)0)
|
||||
#define aec_spk_mic_reset(...) ((void)0)
|
||||
#define aec_spk_mic_process(...) ((int32_t)0)
|
||||
#define aec_spk_mic_release(...) ((void)0)
|
||||
#endif
|
||||
|
||||
#define MAX_TIMESTAMP_DIFF_USEC 200000
|
||||
|
||||
#define MAX_READ_WAIT_TIME_MSEC 80
|
||||
|
||||
uint64_t timespec_to_usec(struct timespec ts) {
|
||||
return (ts.tv_sec * 1e6L + ts.tv_nsec/1000);
|
||||
}
|
||||
|
||||
void get_reference_audio_in_place(struct aec_t *aec, size_t frames) {
|
||||
if (aec->num_reference_channels == aec->spk_num_channels) {
|
||||
/* Reference count equals speaker channels, nothing to do here. */
|
||||
return;
|
||||
} else if (aec->num_reference_channels != 1) {
|
||||
/* We don't have a rule for non-mono references, show error on log */
|
||||
ALOGE("Invalid reference count - must be 1 or match number of playback channels!");
|
||||
return;
|
||||
}
|
||||
int16_t *src_Nch = &aec->spk_buf_playback_format[0];
|
||||
int16_t *dst_1ch = &aec->spk_buf_playback_format[0];
|
||||
int32_t num_channels = (int32_t)aec->spk_num_channels;
|
||||
size_t frame, ch;
|
||||
for (frame = 0; frame < frames; frame++) {
|
||||
int32_t acc = 0;
|
||||
for (ch = 0; ch < aec->spk_num_channels; ch++) {
|
||||
acc += src_Nch[ch];
|
||||
}
|
||||
*dst_1ch++ = clamp16(acc/num_channels);
|
||||
src_Nch += aec->spk_num_channels;
|
||||
}
|
||||
}
|
||||
|
||||
void print_queue_status_to_log(struct aec_t *aec, bool write_side) {
|
||||
ssize_t q1 = fifo_available_to_read(aec->spk_fifo);
|
||||
ssize_t q2 = fifo_available_to_read(aec->ts_fifo);
|
||||
|
||||
ALOGV("Queue available %s: Spk %zd (count %zd) TS %zd (count %zd)",
|
||||
(write_side) ? "(POST-WRITE)" : "(PRE-READ)",
|
||||
q1, q1/aec->spk_frame_size_bytes/PLAYBACK_PERIOD_SIZE,
|
||||
q2, q2/sizeof(struct aec_info));
|
||||
}
|
||||
|
||||
void flush_aec_fifos(struct aec_t *aec) {
|
||||
if (aec == NULL) {
|
||||
return;
|
||||
}
|
||||
if (aec->spk_fifo != NULL) {
|
||||
ALOGV("Flushing AEC Spk FIFO...");
|
||||
fifo_flush(aec->spk_fifo);
|
||||
}
|
||||
if (aec->ts_fifo != NULL) {
|
||||
ALOGV("Flushing AEC Timestamp FIFO...");
|
||||
fifo_flush(aec->ts_fifo);
|
||||
}
|
||||
/* Reset FIFO read-write offset tracker */
|
||||
aec->read_write_diff_bytes = 0;
|
||||
}
|
||||
|
||||
void aec_set_spk_running_no_lock(struct aec_t* aec, bool state) {
|
||||
aec->spk_running = state;
|
||||
}
|
||||
|
||||
bool aec_get_spk_running_no_lock(struct aec_t* aec) {
|
||||
return aec->spk_running;
|
||||
}
|
||||
|
||||
void destroy_aec_reference_config_no_lock(struct aec_t* aec) {
|
||||
if (!aec->spk_initialized) {
|
||||
return;
|
||||
}
|
||||
aec_set_spk_running_no_lock(aec, false);
|
||||
fifo_release(aec->spk_fifo);
|
||||
fifo_release(aec->ts_fifo);
|
||||
memset(&aec->last_spk_info, 0, sizeof(struct aec_info));
|
||||
aec->spk_initialized = false;
|
||||
}
|
||||
|
||||
void destroy_aec_mic_config_no_lock(struct aec_t* aec) {
|
||||
if (!aec->mic_initialized) {
|
||||
return;
|
||||
}
|
||||
release_resampler(aec->spk_resampler);
|
||||
free(aec->mic_buf);
|
||||
free(aec->spk_buf);
|
||||
free(aec->spk_buf_playback_format);
|
||||
free(aec->spk_buf_resampler_out);
|
||||
memset(&aec->last_mic_info, 0, sizeof(struct aec_info));
|
||||
aec->mic_initialized = false;
|
||||
}
|
||||
|
||||
struct aec_t* init_aec_interface(struct aec_params* params) {
|
||||
ALOGV("%s enter", __func__);
|
||||
struct aec_t *aec = (struct aec_t *)calloc(1, sizeof(struct aec_t));
|
||||
if (aec == NULL) {
|
||||
ALOGE("%s: Failed to allocate memory for AEC interface!", __func__);
|
||||
ALOGV("%s exit", __func__);
|
||||
return NULL;
|
||||
}
|
||||
pthread_mutex_init(&aec->lock, NULL);
|
||||
|
||||
aec->num_reference_channels = params->num_reference_channels;
|
||||
/* Set defaults, will be overridden by settings in init_aec_(mic|referece_config) */
|
||||
/* Capture settings */
|
||||
aec->mic_sampling_rate = params->mic_sampling_rate_hz;
|
||||
aec->mic_frame_size_bytes = params->num_mic_channels * sizeof(int32_t);
|
||||
aec->mic_num_channels = params->num_mic_channels;
|
||||
|
||||
/* Playback settings (before conversion to reference) */
|
||||
aec->spk_sampling_rate = params->playback_sampling_rate_hz;
|
||||
aec->spk_frame_size_bytes = params->num_playback_channels * sizeof(int32_t);
|
||||
aec->spk_num_channels = params->num_playback_channels;
|
||||
|
||||
ALOGV("%s exit", __func__);
|
||||
return aec;
|
||||
}
|
||||
|
||||
void release_aec_interface(struct aec_t *aec) {
|
||||
ALOGV("%s enter", __func__);
|
||||
pthread_mutex_lock(&aec->lock);
|
||||
destroy_aec_mic_config_no_lock(aec);
|
||||
destroy_aec_reference_config_no_lock(aec);
|
||||
pthread_mutex_unlock(&aec->lock);
|
||||
free(aec);
|
||||
ALOGV("%s exit", __func__);
|
||||
}
|
||||
|
||||
int init_aec(struct aec_params* params, struct aec_t** aec_ptr) {
|
||||
ALOGV("%s enter", __func__);
|
||||
if ((params == NULL) || (aec_ptr == NULL)) {
|
||||
ALOGE("%s: Invalid input arguments!", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (aec_spk_mic_init(params->mic_sampling_rate, params->num_reference_channels,
|
||||
params->num_mic_channels)) {
|
||||
ALOGE("%s: AEC object failed to initialize!", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
struct aec_t* aec = init_aec_interface(params);
|
||||
if (aec == NULL) {
|
||||
ALOGE("%s: Failed to allocate AEC struct!", __func__);
|
||||
goto error_1;
|
||||
}
|
||||
(*aec_ptr) = aec;
|
||||
ALOGV("%s exit", __func__);
|
||||
return 0;
|
||||
|
||||
error_1:
|
||||
aec_spk_mic_release();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
void release_aec(struct aec_t *aec) {
|
||||
ALOGV("%s enter", __func__);
|
||||
if (aec == NULL) {
|
||||
return;
|
||||
}
|
||||
release_aec_interface(aec);
|
||||
aec_spk_mic_release();
|
||||
ALOGV("%s exit", __func__);
|
||||
}
|
||||
|
||||
int init_aec_reference_config(struct aec_t *aec, struct alsa_stream_out *out) {
|
||||
ALOGV("%s enter", __func__);
|
||||
if (!aec) {
|
||||
ALOGE("AEC: No valid interface found!");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
pthread_mutex_lock(&aec->lock);
|
||||
if (aec->spk_initialized) {
|
||||
destroy_aec_reference_config_no_lock(aec);
|
||||
}
|
||||
|
||||
aec->spk_fifo = fifo_init(
|
||||
out->config.period_count * out->config.period_size *
|
||||
audio_stream_out_frame_size(&out->stream),
|
||||
false /* reader_throttles_writer */);
|
||||
if (aec->spk_fifo == NULL) {
|
||||
ALOGE("AEC: Speaker loopback FIFO Init failed!");
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
aec->ts_fifo = fifo_init(
|
||||
out->config.period_count * sizeof(struct aec_info),
|
||||
false /* reader_throttles_writer */);
|
||||
if (aec->ts_fifo == NULL) {
|
||||
ALOGE("AEC: Speaker timestamp FIFO Init failed!");
|
||||
ret = -EINVAL;
|
||||
fifo_release(aec->spk_fifo);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
aec->spk_sampling_rate = out->config.rate;
|
||||
aec->spk_frame_size_bytes = audio_stream_out_frame_size(&out->stream);
|
||||
aec->spk_num_channels = out->config.channels;
|
||||
aec->spk_initialized = true;
|
||||
exit:
|
||||
pthread_mutex_unlock(&aec->lock);
|
||||
ALOGV("%s exit", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void destroy_aec_reference_config(struct aec_t* aec) {
|
||||
ALOGV("%s enter", __func__);
|
||||
if (aec == NULL) {
|
||||
ALOGV("%s exit", __func__);
|
||||
return;
|
||||
}
|
||||
pthread_mutex_lock(&aec->lock);
|
||||
destroy_aec_reference_config_no_lock(aec);
|
||||
pthread_mutex_unlock(&aec->lock);
|
||||
ALOGV("%s exit", __func__);
|
||||
}
|
||||
|
||||
int write_to_reference_fifo(struct aec_t* aec, void* buffer, struct aec_info* info) {
|
||||
ALOGV("%s enter", __func__);
|
||||
int ret = 0;
|
||||
size_t bytes = info->bytes;
|
||||
|
||||
/* Write audio samples to FIFO */
|
||||
ssize_t written_bytes = fifo_write(aec->spk_fifo, buffer, bytes);
|
||||
if (written_bytes != bytes) {
|
||||
ALOGE("Could only write %zu of %zu bytes", written_bytes, bytes);
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
|
||||
/* Write timestamp to FIFO */
|
||||
info->bytes = written_bytes;
|
||||
ALOGV("Speaker timestamp: %ld s, %ld nsec", info->timestamp.tv_sec, info->timestamp.tv_nsec);
|
||||
ssize_t ts_bytes = fifo_write(aec->ts_fifo, info, sizeof(struct aec_info));
|
||||
ALOGV("Wrote TS bytes: %zu", ts_bytes);
|
||||
print_queue_status_to_log(aec, true);
|
||||
ALOGV("%s exit", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void get_spk_timestamp(struct aec_t* aec, ssize_t read_bytes, uint64_t* spk_time) {
|
||||
*spk_time = 0;
|
||||
uint64_t spk_time_offset = 0;
|
||||
float usec_per_byte = 1E6 / ((float)(aec->spk_frame_size_bytes * aec->spk_sampling_rate));
|
||||
if (aec->read_write_diff_bytes < 0) {
|
||||
/* We're still reading a previous write packet. (We only need the first sample's timestamp,
|
||||
* so even if we straddle packets we only care about the first one)
|
||||
* So we just use the previous timestamp, with an appropriate offset
|
||||
* based on the number of bytes remaining to be read from that write packet. */
|
||||
spk_time_offset = (aec->last_spk_info.bytes + aec->read_write_diff_bytes) * usec_per_byte;
|
||||
ALOGV("Reusing previous timestamp, calculated offset (usec) %" PRIu64, spk_time_offset);
|
||||
} else {
|
||||
/* If read_write_diff_bytes > 0, there are no new writes, so there won't be timestamps in
|
||||
* the FIFO, and the check below will fail. */
|
||||
if (!fifo_available_to_read(aec->ts_fifo)) {
|
||||
ALOGE("Timestamp error: no new timestamps!");
|
||||
return;
|
||||
}
|
||||
/* We just read valid data, so if we're here, we should have a valid timestamp to use. */
|
||||
ssize_t ts_bytes = fifo_read(aec->ts_fifo, &aec->last_spk_info, sizeof(struct aec_info));
|
||||
ALOGV("Read TS bytes: %zd, expected %zu", ts_bytes, sizeof(struct aec_info));
|
||||
aec->read_write_diff_bytes -= aec->last_spk_info.bytes;
|
||||
}
|
||||
|
||||
*spk_time = timespec_to_usec(aec->last_spk_info.timestamp) + spk_time_offset;
|
||||
|
||||
aec->read_write_diff_bytes += read_bytes;
|
||||
struct aec_info spk_info = aec->last_spk_info;
|
||||
while (aec->read_write_diff_bytes > 0) {
|
||||
/* If read_write_diff_bytes > 0, it means that there are more write packet timestamps
|
||||
* in FIFO (since there we read more valid data the size of the current timestamp's
|
||||
* packet). Keep reading timestamps from FIFO to get to the most recent one. */
|
||||
if (!fifo_available_to_read(aec->ts_fifo)) {
|
||||
/* There are no more timestamps, we have the most recent one. */
|
||||
ALOGV("At the end of timestamp FIFO, breaking...");
|
||||
break;
|
||||
}
|
||||
fifo_read(aec->ts_fifo, &spk_info, sizeof(struct aec_info));
|
||||
ALOGV("Fast-forwarded timestamp by %zd bytes, remaining bytes: %zd,"
|
||||
" new timestamp (usec) %" PRIu64,
|
||||
spk_info.bytes, aec->read_write_diff_bytes, timespec_to_usec(spk_info.timestamp));
|
||||
aec->read_write_diff_bytes -= spk_info.bytes;
|
||||
}
|
||||
aec->last_spk_info = spk_info;
|
||||
}
|
||||
|
||||
int get_reference_samples(struct aec_t* aec, void* buffer, struct aec_info* info) {
|
||||
ALOGV("%s enter", __func__);
|
||||
|
||||
if (!aec->spk_initialized) {
|
||||
ALOGE("%s called with no reference initialized", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
size_t bytes = info->bytes;
|
||||
const size_t frames =
|
||||
bytes * aec->num_reference_channels / aec->mic_num_channels / aec->mic_frame_size_bytes;
|
||||
const size_t sample_rate_ratio = aec->spk_sampling_rate / aec->mic_sampling_rate;
|
||||
const size_t resampler_in_frames = frames * sample_rate_ratio;
|
||||
|
||||
/* Read audio samples from FIFO */
|
||||
const size_t req_bytes = resampler_in_frames * aec->spk_frame_size_bytes;
|
||||
ssize_t available_bytes = 0;
|
||||
unsigned int wait_count = MAX_READ_WAIT_TIME_MSEC;
|
||||
while (true) {
|
||||
available_bytes = fifo_available_to_read(aec->spk_fifo);
|
||||
if (available_bytes >= req_bytes) {
|
||||
break;
|
||||
} else if (available_bytes < 0) {
|
||||
ALOGE("fifo_read returned code %zu ", available_bytes);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ALOGV("Sleeping, required bytes: %zu, available bytes: %zd", req_bytes, available_bytes);
|
||||
usleep(1000);
|
||||
if ((wait_count--) == 0) {
|
||||
ALOGE("Timed out waiting for read from reference FIFO");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
const size_t read_bytes = fifo_read(aec->spk_fifo, aec->spk_buf_playback_format, req_bytes);
|
||||
|
||||
/* Get timestamp*/
|
||||
get_spk_timestamp(aec, read_bytes, &info->timestamp_usec);
|
||||
|
||||
/* Get reference - could be mono, downmixed from multichannel.
|
||||
* Reference stored at spk_buf_playback_format */
|
||||
get_reference_audio_in_place(aec, resampler_in_frames);
|
||||
|
||||
int16_t* resampler_out_buf;
|
||||
/* Resample to mic sampling rate (16-bit resampler) */
|
||||
if (aec->spk_resampler != NULL) {
|
||||
size_t in_frame_count = resampler_in_frames;
|
||||
size_t out_frame_count = frames;
|
||||
aec->spk_resampler->resample_from_input(aec->spk_resampler, aec->spk_buf_playback_format,
|
||||
&in_frame_count, aec->spk_buf_resampler_out,
|
||||
&out_frame_count);
|
||||
resampler_out_buf = aec->spk_buf_resampler_out;
|
||||
} else {
|
||||
if (sample_rate_ratio != 1) {
|
||||
ALOGE("Speaker sample rate %d, mic sample rate %d but no resampler defined!",
|
||||
aec->spk_sampling_rate, aec->mic_sampling_rate);
|
||||
}
|
||||
resampler_out_buf = aec->spk_buf_playback_format;
|
||||
}
|
||||
|
||||
/* Convert to 32 bit */
|
||||
int16_t* src16 = resampler_out_buf;
|
||||
int32_t* dst32 = buffer;
|
||||
size_t frame, ch;
|
||||
for (frame = 0; frame < frames; frame++) {
|
||||
for (ch = 0; ch < aec->num_reference_channels; ch++) {
|
||||
*dst32++ = ((int32_t)*src16++) << 16;
|
||||
}
|
||||
}
|
||||
|
||||
info->bytes = bytes;
|
||||
|
||||
ALOGV("%s exit", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_aec_mic_config(struct aec_t *aec, struct alsa_stream_in *in) {
|
||||
ALOGV("%s enter", __func__);
|
||||
#if DEBUG_AEC
|
||||
remove("/data/local/traces/aec_in.pcm");
|
||||
remove("/data/local/traces/aec_out.pcm");
|
||||
remove("/data/local/traces/aec_ref.pcm");
|
||||
remove("/data/local/traces/aec_timestamps.txt");
|
||||
#endif /* #if DEBUG_AEC */
|
||||
|
||||
if (!aec) {
|
||||
ALOGE("AEC: No valid interface found!");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
pthread_mutex_lock(&aec->lock);
|
||||
if (aec->mic_initialized) {
|
||||
destroy_aec_mic_config_no_lock(aec);
|
||||
}
|
||||
aec->mic_sampling_rate = in->config.rate;
|
||||
aec->mic_frame_size_bytes = audio_stream_in_frame_size(&in->stream);
|
||||
aec->mic_num_channels = in->config.channels;
|
||||
|
||||
aec->mic_buf_size_bytes = in->config.period_size * aec->mic_frame_size_bytes;
|
||||
aec->mic_buf = (int32_t *)malloc(aec->mic_buf_size_bytes);
|
||||
if (aec->mic_buf == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
memset(aec->mic_buf, 0, aec->mic_buf_size_bytes);
|
||||
/* Reference buffer is the same number of frames as mic,
|
||||
* only with a different number of channels in the frame. */
|
||||
aec->spk_buf_size_bytes = in->config.period_size * aec->spk_num_channels *
|
||||
aec->mic_frame_size_bytes / aec->mic_num_channels;
|
||||
aec->spk_buf = (int32_t *)malloc(aec->spk_buf_size_bytes);
|
||||
if (aec->spk_buf == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto exit_1;
|
||||
}
|
||||
memset(aec->spk_buf, 0, aec->spk_buf_size_bytes);
|
||||
|
||||
/* Pre-resampler buffer */
|
||||
size_t spk_frame_out_format_bytes =
|
||||
aec->spk_buf_size_bytes * aec->spk_sampling_rate / aec->mic_sampling_rate;
|
||||
aec->spk_buf_playback_format = (int16_t *)malloc(spk_frame_out_format_bytes);
|
||||
if (aec->spk_buf_playback_format == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto exit_2;
|
||||
}
|
||||
/* Resampler is 16-bit */
|
||||
aec->spk_buf_resampler_out = (int16_t *)malloc(aec->spk_buf_size_bytes);
|
||||
if (aec->spk_buf_resampler_out == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto exit_3;
|
||||
}
|
||||
|
||||
/* Don't use resampler if it's not required */
|
||||
if (in->config.rate == aec->spk_sampling_rate) {
|
||||
aec->spk_resampler = NULL;
|
||||
} else {
|
||||
int resampler_ret = create_resampler(
|
||||
aec->spk_sampling_rate, in->config.rate, aec->num_reference_channels,
|
||||
RESAMPLER_QUALITY_MAX - 1, /* MAX - 1 is the real max */
|
||||
NULL, /* resampler_buffer_provider */
|
||||
&aec->spk_resampler);
|
||||
if (resampler_ret) {
|
||||
ALOGE("AEC: Resampler initialization failed! Error code %d", resampler_ret);
|
||||
ret = resampler_ret;
|
||||
goto exit_4;
|
||||
}
|
||||
}
|
||||
|
||||
flush_aec_fifos(aec);
|
||||
aec_spk_mic_reset();
|
||||
aec->mic_initialized = true;
|
||||
|
||||
exit:
|
||||
pthread_mutex_unlock(&aec->lock);
|
||||
ALOGV("%s exit", __func__);
|
||||
return ret;
|
||||
|
||||
exit_4:
|
||||
free(aec->spk_buf_resampler_out);
|
||||
exit_3:
|
||||
free(aec->spk_buf_playback_format);
|
||||
exit_2:
|
||||
free(aec->spk_buf);
|
||||
exit_1:
|
||||
free(aec->mic_buf);
|
||||
pthread_mutex_unlock(&aec->lock);
|
||||
ALOGV("%s exit", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void aec_set_spk_running(struct aec_t *aec, bool state) {
|
||||
ALOGV("%s enter", __func__);
|
||||
pthread_mutex_lock(&aec->lock);
|
||||
aec_set_spk_running_no_lock(aec, state);
|
||||
pthread_mutex_unlock(&aec->lock);
|
||||
ALOGV("%s exit", __func__);
|
||||
}
|
||||
|
||||
bool aec_get_spk_running(struct aec_t *aec) {
|
||||
ALOGV("%s enter", __func__);
|
||||
pthread_mutex_lock(&aec->lock);
|
||||
bool state = aec_get_spk_running_no_lock(aec);
|
||||
pthread_mutex_unlock(&aec->lock);
|
||||
ALOGV("%s exit", __func__);
|
||||
return state;
|
||||
}
|
||||
|
||||
void destroy_aec_mic_config(struct aec_t* aec) {
|
||||
ALOGV("%s enter", __func__);
|
||||
if (aec == NULL) {
|
||||
ALOGV("%s exit", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&aec->lock);
|
||||
destroy_aec_mic_config_no_lock(aec);
|
||||
pthread_mutex_unlock(&aec->lock);
|
||||
ALOGV("%s exit", __func__);
|
||||
}
|
||||
|
||||
#ifdef AEC_HAL
|
||||
int process_aec(struct aec_t *aec, void* buffer, struct aec_info *info) {
|
||||
ALOGV("%s enter", __func__);
|
||||
int ret = 0;
|
||||
|
||||
if (aec == NULL) {
|
||||
ALOGE("AEC: Interface uninitialized! Cannot process.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((!aec->mic_initialized) || (!aec->spk_initialized)) {
|
||||
ALOGE("%s called with initialization: mic: %d, spk: %d", __func__, aec->mic_initialized,
|
||||
aec->spk_initialized);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
size_t bytes = info->bytes;
|
||||
|
||||
size_t frame_size = aec->mic_frame_size_bytes;
|
||||
size_t in_frames = bytes / frame_size;
|
||||
|
||||
/* Copy raw mic samples to AEC input buffer */
|
||||
memcpy(aec->mic_buf, buffer, bytes);
|
||||
|
||||
uint64_t mic_time = timespec_to_usec(info->timestamp);
|
||||
uint64_t spk_time = 0;
|
||||
|
||||
/*
|
||||
* Only run AEC if there is speaker playback.
|
||||
* The first time speaker state changes to running, flush FIFOs, so we're not stuck
|
||||
* processing stale reference input.
|
||||
*/
|
||||
bool spk_running = aec_get_spk_running(aec);
|
||||
|
||||
if (!spk_running) {
|
||||
/* No new playback samples, so don't run AEC.
|
||||
* 'buffer' already contains input samples. */
|
||||
ALOGV("Speaker not running, skipping AEC..");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!aec->prev_spk_running) {
|
||||
flush_aec_fifos(aec);
|
||||
}
|
||||
|
||||
/* If there's no data in FIFO, exit */
|
||||
if (fifo_available_to_read(aec->spk_fifo) <= 0) {
|
||||
ALOGV("Echo reference buffer empty, zeroing reference....");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
print_queue_status_to_log(aec, false);
|
||||
|
||||
/* Get reference, with format and sample rate required by AEC */
|
||||
struct aec_info spk_info;
|
||||
spk_info.bytes = bytes;
|
||||
int ref_ret = get_reference_samples(aec, aec->spk_buf, &spk_info);
|
||||
spk_time = spk_info.timestamp_usec;
|
||||
|
||||
if (ref_ret) {
|
||||
ALOGE("get_reference_samples returned code %d", ref_ret);
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
int64_t time_diff = (mic_time > spk_time) ? (mic_time - spk_time) : (spk_time - mic_time);
|
||||
if ((spk_time == 0) || (mic_time == 0) || (time_diff > MAX_TIMESTAMP_DIFF_USEC)) {
|
||||
ALOGV("Speaker-mic timestamps diverged, skipping AEC");
|
||||
flush_aec_fifos(aec);
|
||||
aec_spk_mic_reset();
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ALOGV("Mic time: %"PRIu64", spk time: %"PRIu64, mic_time, spk_time);
|
||||
|
||||
/*
|
||||
* AEC processing call - output stored at 'buffer'
|
||||
*/
|
||||
int32_t aec_status = aec_spk_mic_process(
|
||||
aec->spk_buf, spk_time,
|
||||
aec->mic_buf, mic_time,
|
||||
in_frames,
|
||||
buffer);
|
||||
|
||||
if (!aec_status) {
|
||||
ALOGE("AEC processing failed!");
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
exit:
|
||||
aec->prev_spk_running = spk_running;
|
||||
ALOGV("Mic time: %"PRIu64", spk time: %"PRIu64, mic_time, spk_time);
|
||||
if (ret) {
|
||||
/* Best we can do is copy over the raw mic signal */
|
||||
memcpy(buffer, aec->mic_buf, bytes);
|
||||
flush_aec_fifos(aec);
|
||||
aec_spk_mic_reset();
|
||||
}
|
||||
|
||||
#if DEBUG_AEC
|
||||
/* ref data is 32-bit at this point */
|
||||
size_t ref_bytes = in_frames*aec->num_reference_channels*sizeof(int32_t);
|
||||
|
||||
FILE *fp_in = fopen("/data/local/traces/aec_in.pcm", "a+");
|
||||
if (fp_in) {
|
||||
fwrite((char *)aec->mic_buf, 1, bytes, fp_in);
|
||||
fclose(fp_in);
|
||||
} else {
|
||||
ALOGE("AEC debug: Could not open file aec_in.pcm!");
|
||||
}
|
||||
FILE *fp_out = fopen("/data/local/traces/aec_out.pcm", "a+");
|
||||
if (fp_out) {
|
||||
fwrite((char *)buffer, 1, bytes, fp_out);
|
||||
fclose(fp_out);
|
||||
} else {
|
||||
ALOGE("AEC debug: Could not open file aec_out.pcm!");
|
||||
}
|
||||
FILE *fp_ref = fopen("/data/local/traces/aec_ref.pcm", "a+");
|
||||
if (fp_ref) {
|
||||
fwrite((char *)aec->spk_buf, 1, ref_bytes, fp_ref);
|
||||
fclose(fp_ref);
|
||||
} else {
|
||||
ALOGE("AEC debug: Could not open file aec_ref.pcm!");
|
||||
}
|
||||
FILE *fp_ts = fopen("/data/local/traces/aec_timestamps.txt", "a+");
|
||||
if (fp_ts) {
|
||||
fprintf(fp_ts, "%"PRIu64",%"PRIu64"\n", mic_time, spk_time);
|
||||
fclose(fp_ts);
|
||||
} else {
|
||||
ALOGE("AEC debug: Could not open file aec_timestamps.txt!");
|
||||
}
|
||||
#endif /* #if DEBUG_AEC */
|
||||
ALOGV("%s exit", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /*#ifdef AEC_HAL*/
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Definitions and interface related to HAL implementations of Acoustic Echo Canceller (AEC).
|
||||
*
|
||||
* AEC cleans the microphone signal by removing from it audio data corresponding to loudspeaker
|
||||
* playback. Note that this process can be nonlinear.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AUDIO_AEC_H_
|
||||
#define _AUDIO_AEC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#include <hardware/audio.h>
|
||||
#include <audio_utils/resampler.h>
|
||||
#include "audio_hw.h"
|
||||
#include "fifo_wrapper.h"
|
||||
|
||||
struct aec_t {
|
||||
pthread_mutex_t lock;
|
||||
size_t num_reference_channels;
|
||||
bool mic_initialized;
|
||||
int32_t *mic_buf;
|
||||
size_t mic_num_channels;
|
||||
size_t mic_buf_size_bytes;
|
||||
size_t mic_frame_size_bytes;
|
||||
uint32_t mic_sampling_rate;
|
||||
struct aec_info last_mic_info;
|
||||
bool spk_initialized;
|
||||
int32_t *spk_buf;
|
||||
size_t spk_num_channels;
|
||||
size_t spk_buf_size_bytes;
|
||||
size_t spk_frame_size_bytes;
|
||||
uint32_t spk_sampling_rate;
|
||||
struct aec_info last_spk_info;
|
||||
int16_t *spk_buf_playback_format;
|
||||
int16_t *spk_buf_resampler_out;
|
||||
void *spk_fifo;
|
||||
void *ts_fifo;
|
||||
ssize_t read_write_diff_bytes;
|
||||
struct resampler_itfe *spk_resampler;
|
||||
bool spk_running;
|
||||
bool prev_spk_running;
|
||||
};
|
||||
|
||||
struct aec_params {
|
||||
int num_mic_channels;
|
||||
int num_reference_channels;
|
||||
int num_playback_channels;
|
||||
int mic_sampling_rate_hz;
|
||||
int playback_sampling_rate_hz;
|
||||
};
|
||||
|
||||
/* Initialize AEC object.
|
||||
* This must be called when the audio device is opened.
|
||||
* ALSA device mutex must be held before calling this API.
|
||||
* Returns -EINVAL if AEC object fails to initialize, else returns 0. */
|
||||
int init_aec(struct aec_params* params, struct aec_t** aec_ptr);
|
||||
|
||||
/* Release AEC object.
|
||||
* This must be called when the audio device is closed. */
|
||||
void release_aec(struct aec_t* aec);
|
||||
|
||||
/* Initialize reference configuration for AEC.
|
||||
* Must be called when a new output stream is opened.
|
||||
* Returns -EINVAL if any processing block fails to initialize,
|
||||
* else returns 0. */
|
||||
int init_aec_reference_config (struct aec_t *aec, struct alsa_stream_out *out);
|
||||
|
||||
/* Clear reference configuration for AEC.
|
||||
* Must be called when the output stream is closed. */
|
||||
void destroy_aec_reference_config (struct aec_t *aec);
|
||||
|
||||
/* Initialize microphone configuration for AEC.
|
||||
* Must be called when a new input stream is opened.
|
||||
* Returns -EINVAL if any processing block fails to initialize,
|
||||
* else returns 0. */
|
||||
int init_aec_mic_config(struct aec_t* aec, struct alsa_stream_in* in);
|
||||
|
||||
/* Clear microphone configuration for AEC.
|
||||
* Must be called when the input stream is closed. */
|
||||
void destroy_aec_mic_config (struct aec_t *aec);
|
||||
|
||||
/* Used to communicate playback state (running or not) to AEC interface.
|
||||
* This is used by process_aec() to determine if AEC processing is to be run. */
|
||||
void aec_set_spk_running (struct aec_t *aec, bool state);
|
||||
|
||||
/* Used to communicate playback state (running or not) to the caller. */
|
||||
bool aec_get_spk_running(struct aec_t* aec);
|
||||
|
||||
/* Write audio samples to AEC reference FIFO for use in AEC.
|
||||
* Both audio samples and timestamps are added in FIFO fashion.
|
||||
* Must be called after every write to PCM.
|
||||
* Returns -ENOMEM if the write fails, else returns 0. */
|
||||
int write_to_reference_fifo(struct aec_t* aec, void* buffer, struct aec_info* info);
|
||||
|
||||
/* Get reference audio samples + timestamp, in the format expected by AEC,
|
||||
* i.e. same sample rate and bit rate as microphone audio.
|
||||
* Timestamp is updated in field 'timestamp_usec', and not in 'timestamp'.
|
||||
* Returns:
|
||||
* -EINVAL if the AEC object is invalid.
|
||||
* -ENOMEM if the reference FIFO overflows or is corrupted.
|
||||
* -ETIMEDOUT if we timed out waiting for the requested number of bytes
|
||||
* 0 otherwise */
|
||||
int get_reference_samples(struct aec_t* aec, void* buffer, struct aec_info* info);
|
||||
|
||||
#ifdef AEC_HAL
|
||||
|
||||
/* Processing function call for AEC.
|
||||
* AEC output is updated at location pointed to by 'buffer'.
|
||||
* This function does not run AEC when there is no playback -
|
||||
* as communicated to this AEC interface using aec_set_spk_running().
|
||||
* Returns -EINVAL if processing fails, else returns 0. */
|
||||
int process_aec(struct aec_t* aec, void* buffer, struct aec_info* info);
|
||||
|
||||
#else /* #ifdef AEC_HAL */
|
||||
|
||||
#define process_aec(...) ((int)0)
|
||||
|
||||
#endif /* #ifdef AEC_HAL */
|
||||
|
||||
#endif /* _AUDIO_AEC_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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 _YUKAWA_AUDIO_HW_H_
|
||||
#define _YUKAWA_AUDIO_HW_H_
|
||||
|
||||
#include <hardware/audio.h>
|
||||
#include <tinyalsa/asoundlib.h>
|
||||
|
||||
#include "fir_filter.h"
|
||||
|
||||
#define CARD_OUT 0
|
||||
#define PORT_HDMI 0
|
||||
#define PORT_INTERNAL_SPEAKER 1
|
||||
#define CARD_IN 0
|
||||
#define PORT_BUILTIN_MIC 3
|
||||
|
||||
#define MIXER_XML_PATH "/vendor/etc/mixer_paths.xml"
|
||||
/* Minimum granularity - Arbitrary but small value */
|
||||
#define CODEC_BASE_FRAME_COUNT 32
|
||||
|
||||
#define CHANNEL_STEREO 2
|
||||
|
||||
#ifdef AEC_HAL
|
||||
#define NUM_AEC_REFERENCE_CHANNELS 1
|
||||
#else
|
||||
/* App AEC uses 2-channel reference */
|
||||
#define NUM_AEC_REFERENCE_CHANNELS 2
|
||||
#endif /* #ifdef AEC_HAL */
|
||||
|
||||
#define DEBUG_AEC 0
|
||||
|
||||
#define PCM_OPEN_RETRIES 100
|
||||
#define PCM_OPEN_WAIT_TIME_MS 20
|
||||
|
||||
/* Capture codec parameters */
|
||||
/* Set up a capture period of 32 ms:
|
||||
* CAPTURE_PERIOD = PERIOD_SIZE / SAMPLE_RATE, so (32e-3) = PERIOD_SIZE / (16e3)
|
||||
* => PERIOD_SIZE = 512 frames, where each "frame" consists of 1 sample of every channel (here, 2ch) */
|
||||
#define CAPTURE_PERIOD_MULTIPLIER 16
|
||||
#define CAPTURE_PERIOD_SIZE (CODEC_BASE_FRAME_COUNT * CAPTURE_PERIOD_MULTIPLIER)
|
||||
#define CAPTURE_PERIOD_COUNT 4
|
||||
#define CAPTURE_PERIOD_START_THRESHOLD 0
|
||||
#define CAPTURE_CODEC_SAMPLING_RATE 16000
|
||||
|
||||
/* Playback codec parameters */
|
||||
/* number of base blocks in a short period (low latency) */
|
||||
#define PLAYBACK_PERIOD_MULTIPLIER 32 /* 21 ms */
|
||||
/* number of frames per short period (low latency) */
|
||||
#define PLAYBACK_PERIOD_SIZE (CODEC_BASE_FRAME_COUNT * PLAYBACK_PERIOD_MULTIPLIER)
|
||||
/* number of pseudo periods for low latency playback */
|
||||
#define PLAYBACK_PERIOD_COUNT 4
|
||||
#define PLAYBACK_PERIOD_START_THRESHOLD 2
|
||||
#define PLAYBACK_CODEC_SAMPLING_RATE 48000
|
||||
#define MIN_WRITE_SLEEP_US 5000
|
||||
|
||||
#define SPEAKER_EQ_FILE "/vendor/etc/speaker_eq_sei610.fir"
|
||||
#define SPEAKER_MAX_EQ_LENGTH 512
|
||||
|
||||
struct alsa_audio_device {
|
||||
struct audio_hw_device hw_device;
|
||||
|
||||
pthread_mutex_t lock; /* see notes in in_read/out_write on mutex acquisition order */
|
||||
struct alsa_stream_in *active_input;
|
||||
struct alsa_stream_out *active_output;
|
||||
struct audio_route *audio_route;
|
||||
struct mixer *mixer;
|
||||
bool mic_mute;
|
||||
struct aec_t *aec;
|
||||
};
|
||||
|
||||
struct alsa_stream_in {
|
||||
struct audio_stream_in stream;
|
||||
|
||||
pthread_mutex_t lock; /* see note in in_read() on mutex acquisition order */
|
||||
audio_devices_t devices;
|
||||
struct pcm_config config;
|
||||
struct pcm *pcm;
|
||||
bool unavailable;
|
||||
bool standby;
|
||||
struct alsa_audio_device *dev;
|
||||
int read_threshold;
|
||||
unsigned int frames_read;
|
||||
uint64_t timestamp_nsec;
|
||||
audio_source_t source;
|
||||
};
|
||||
|
||||
struct alsa_stream_out {
|
||||
struct audio_stream_out stream;
|
||||
|
||||
pthread_mutex_t lock; /* see note in out_write() on mutex acquisition order */
|
||||
audio_devices_t devices;
|
||||
struct pcm_config config;
|
||||
struct pcm *pcm;
|
||||
bool unavailable;
|
||||
int standby;
|
||||
struct alsa_audio_device *dev;
|
||||
int write_threshold;
|
||||
unsigned int frames_written;
|
||||
struct timespec timestamp;
|
||||
fir_filter_t* speaker_eq;
|
||||
};
|
||||
|
||||
/* 'bytes' are the number of bytes written to audio FIFO, for which 'timestamp' is valid.
|
||||
* 'available' is the number of frames available to read (for input) or yet to be played
|
||||
* (for output) frames in the PCM buffer.
|
||||
* timestamp and available are updated by pcm_get_htimestamp(), so they use the same
|
||||
* datatypes as the corresponding arguments to that function. */
|
||||
struct aec_info {
|
||||
struct timespec timestamp;
|
||||
uint64_t timestamp_usec;
|
||||
unsigned int available;
|
||||
size_t bytes;
|
||||
};
|
||||
|
||||
#endif /* #ifndef _YUKAWA_AUDIO_HW_H_ */
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!-- Copyright (C) 2019 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.
|
||||
-->
|
||||
|
||||
<audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<!-- version section contains a “version” tag in the form “major.minor” e.g version=”1.0” -->
|
||||
|
||||
<!-- Global configuration Decalaration -->
|
||||
<globalConfiguration speaker_drc_enabled="true"/>
|
||||
|
||||
|
||||
<!-- Modules section:
|
||||
There is one section per audio HW module present on the platform.
|
||||
Each module section will contains two mandatory tags for audio HAL “halVersion” and “name”.
|
||||
The module names are the same as in current .conf file:
|
||||
“primary”, “A2DP”, “remote_submix”, “USB”
|
||||
Each module will contain the following sections:
|
||||
“devicePorts”: a list of device descriptors for all input and output devices accessible via this
|
||||
module.
|
||||
This contains both permanently attached devices and removable devices.
|
||||
“mixPorts”: listing all output and input streams exposed by the audio HAL
|
||||
“routes”: list of possible connections between input and output devices or between stream and
|
||||
devices.
|
||||
"route": is defined by an attribute:
|
||||
-"type": <mux|mix> means all sources are mutual exclusive (mux) or can be mixed (mix)
|
||||
-"sink": the sink involved in this route
|
||||
-"sources": all the sources than can be connected to the sink via vis route
|
||||
“attachedDevices”: permanently attached devices.
|
||||
The attachedDevices section is a list of devices names. The names correspond to device names
|
||||
defined in <devicePorts> section.
|
||||
“defaultOutputDevice”: device to be used by default when no policy rule applies
|
||||
-->
|
||||
<modules>
|
||||
<!-- Primary Audio HAL -->
|
||||
<module name="primary" halVersion="3.0">
|
||||
<attachedDevices>
|
||||
<item>Speaker</item>
|
||||
<item>Built-In Mic</item>
|
||||
<item>Echo Reference</item>
|
||||
</attachedDevices>
|
||||
<defaultOutputDevice>Speaker</defaultOutputDevice>
|
||||
<mixPorts>
|
||||
<mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
|
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
|
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
|
||||
</mixPort>
|
||||
<mixPort name="HDMI output" role="source">
|
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
|
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
|
||||
</mixPort>
|
||||
<mixPort name="built-in mic" role="sink">
|
||||
<profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
|
||||
samplingRates="16000"
|
||||
channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
|
||||
</mixPort>
|
||||
<mixPort name="echo reference" role="sink">
|
||||
<profile name="echo_reference" format="AUDIO_FORMAT_PCM_32_BIT"
|
||||
samplingRates="48000"
|
||||
channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
|
||||
</mixPort>
|
||||
</mixPorts>
|
||||
<devicePorts>
|
||||
<!-- Output devices declaration, i.e. Sink DEVICE PORT -->
|
||||
<devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
|
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
|
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
|
||||
</devicePort>
|
||||
<devicePort tagName="HDMI Out" role="sink" type="AUDIO_DEVICE_OUT_HDMI" address="">
|
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
|
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
|
||||
</devicePort>
|
||||
<devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source"
|
||||
address="top">
|
||||
<profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
|
||||
samplingRates="16000"
|
||||
channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
|
||||
</devicePort>
|
||||
<devicePort tagName="Echo Reference" type="AUDIO_DEVICE_IN_ECHO_REFERENCE" role="source">
|
||||
<profile name="echo_reference" format="AUDIO_FORMAT_PCM_32_BIT"
|
||||
samplingRates="48000"
|
||||
channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
|
||||
</devicePort>
|
||||
</devicePorts>
|
||||
<!-- route declaration, i.e. list all available sources for a given sink -->
|
||||
<routes>
|
||||
<route type="mix" sink="Speaker"
|
||||
sources="primary output"/>
|
||||
<route type="mix" sink="HDMI Out"
|
||||
sources="HDMI output"/>
|
||||
<route type="mix" sink="built-in mic"
|
||||
sources="Built-In Mic"/>
|
||||
<route type="mix" sink="echo reference"
|
||||
sources="Echo Reference"/>
|
||||
</routes>
|
||||
|
||||
</module>
|
||||
|
||||
<!-- A2dp Input Audio HAL -->
|
||||
<xi:include href="a2dp_in_audio_policy_configuration_7_0.xml"/>
|
||||
|
||||
<!-- Bluetooth Audio HAL -->
|
||||
<xi:include href="bluetooth_audio_policy_configuration_7_0.xml"/>
|
||||
|
||||
<!-- Usb Audio HAL -->
|
||||
<xi:include href="usb_audio_policy_configuration.xml"/>
|
||||
|
||||
<!-- Remote Submix Audio HAL -->
|
||||
<xi:include href="r_submix_audio_policy_configuration.xml"/>
|
||||
|
||||
</modules>
|
||||
<!-- End of Modules section -->
|
||||
|
||||
<!-- Volume section -->
|
||||
|
||||
<xi:include href="audio_policy_volumes.xml"/>
|
||||
<xi:include href="default_volume_tables.xml"/>
|
||||
|
||||
<!-- End of Volume section -->
|
||||
|
||||
</audioPolicyConfiguration>
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!-- Copyright (C) 2019 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.
|
||||
-->
|
||||
|
||||
<audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<!-- version section contains a “version” tag in the form “major.minor” e.g version=”1.0” -->
|
||||
|
||||
<!-- Global configuration Decalaration -->
|
||||
<globalConfiguration speaker_drc_enabled="true"/>
|
||||
|
||||
|
||||
<!-- Modules section:
|
||||
There is one section per audio HW module present on the platform.
|
||||
Each module section will contains two mandatory tags for audio HAL “halVersion” and “name”.
|
||||
The module names are the same as in current .conf file:
|
||||
“primary”, “A2DP”, “remote_submix”, “USB”
|
||||
Each module will contain the following sections:
|
||||
“devicePorts”: a list of device descriptors for all input and output devices accessible via this
|
||||
module.
|
||||
This contains both permanently attached devices and removable devices.
|
||||
“mixPorts”: listing all output and input streams exposed by the audio HAL
|
||||
“routes”: list of possible connections between input and output devices or between stream and
|
||||
devices.
|
||||
"route": is defined by an attribute:
|
||||
-"type": <mux|mix> means all sources are mutual exclusive (mux) or can be mixed (mix)
|
||||
-"sink": the sink involved in this route
|
||||
-"sources": all the sources than can be connected to the sink via vis route
|
||||
“attachedDevices”: permanently attached devices.
|
||||
The attachedDevices section is a list of devices names. The names correspond to device names
|
||||
defined in <devicePorts> section.
|
||||
“defaultOutputDevice”: device to be used by default when no policy rule applies
|
||||
-->
|
||||
<modules>
|
||||
<!-- Primary Audio HAL -->
|
||||
<module name="primary" halVersion="3.0">
|
||||
<attachedDevices>
|
||||
<item>HDMI Out</item>
|
||||
</attachedDevices>
|
||||
<defaultOutputDevice>HDMI Out</defaultOutputDevice>
|
||||
<mixPorts>
|
||||
<mixPort name="HDMI output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
|
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
|
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
|
||||
</mixPort>
|
||||
</mixPorts>
|
||||
<devicePorts>
|
||||
<devicePort tagName="HDMI Out" role="sink" type="AUDIO_DEVICE_OUT_HDMI" address="">
|
||||
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
|
||||
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
|
||||
</devicePort>
|
||||
</devicePorts>
|
||||
<!-- route declaration, i.e. list all available sources for a given sink -->
|
||||
<routes>
|
||||
<route type="mix" sink="HDMI Out"
|
||||
sources="HDMI output"/>
|
||||
</routes>
|
||||
|
||||
</module>
|
||||
|
||||
<!-- A2dp Input Audio HAL -->
|
||||
<xi:include href="a2dp_in_audio_policy_configuration_7_0.xml"/>
|
||||
|
||||
<!-- Bluetooth Audio HAL -->
|
||||
<xi:include href="bluetooth_audio_policy_configuration_7_0.xml"/>
|
||||
|
||||
<!-- Usb Audio HAL -->
|
||||
<xi:include href="usb_audio_policy_configuration.xml"/>
|
||||
|
||||
<!-- Remote Submix Audio HAL -->
|
||||
<xi:include href="r_submix_audio_policy_configuration.xml"/>
|
||||
|
||||
</modules>
|
||||
<!-- End of Modules section -->
|
||||
|
||||
<!-- Volume section -->
|
||||
|
||||
<xi:include href="audio_policy_volumes.xml"/>
|
||||
<xi:include href="default_volume_tables.xml"/>
|
||||
|
||||
<!-- End of Volume section -->
|
||||
|
||||
</audioPolicyConfiguration>
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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 "audio_utils_fifo_wrapper"
|
||||
// #define LOG_NDEBUG 0
|
||||
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <log/log.h>
|
||||
#include <audio_utils/fifo.h>
|
||||
#include "fifo_wrapper.h"
|
||||
|
||||
struct audio_fifo_itfe {
|
||||
audio_utils_fifo *p_fifo;
|
||||
audio_utils_fifo_reader *p_fifo_reader;
|
||||
audio_utils_fifo_writer *p_fifo_writer;
|
||||
int8_t *p_buffer;
|
||||
};
|
||||
|
||||
void *fifo_init(uint32_t bytes, bool reader_throttles_writer) {
|
||||
struct audio_fifo_itfe *interface = new struct audio_fifo_itfe;
|
||||
interface->p_buffer = new int8_t[bytes];
|
||||
if (interface->p_buffer == NULL) {
|
||||
ALOGE("Failed to allocate fifo buffer!");
|
||||
return NULL;
|
||||
}
|
||||
interface->p_fifo = new audio_utils_fifo(bytes, 1, interface->p_buffer, reader_throttles_writer);
|
||||
interface->p_fifo_writer = new audio_utils_fifo_writer(*interface->p_fifo);
|
||||
interface->p_fifo_reader = new audio_utils_fifo_reader(*interface->p_fifo);
|
||||
|
||||
return (void *)interface;
|
||||
}
|
||||
|
||||
void fifo_release(void *fifo_itfe) {
|
||||
struct audio_fifo_itfe *interface = static_cast<struct audio_fifo_itfe *>(fifo_itfe);
|
||||
delete interface->p_fifo_writer;
|
||||
delete interface->p_fifo_reader;
|
||||
delete interface->p_fifo;
|
||||
delete[] interface->p_buffer;
|
||||
delete interface;
|
||||
}
|
||||
|
||||
ssize_t fifo_read(void *fifo_itfe, void *buffer, size_t bytes) {
|
||||
struct audio_fifo_itfe *interface = static_cast<struct audio_fifo_itfe *>(fifo_itfe);
|
||||
return interface->p_fifo_reader->read(buffer, bytes);
|
||||
}
|
||||
|
||||
ssize_t fifo_write(void *fifo_itfe, void *buffer, size_t bytes) {
|
||||
struct audio_fifo_itfe *interface = static_cast<struct audio_fifo_itfe *>(fifo_itfe);
|
||||
return interface->p_fifo_writer->write(buffer, bytes);
|
||||
}
|
||||
|
||||
ssize_t fifo_available_to_read(void *fifo_itfe) {
|
||||
struct audio_fifo_itfe *interface = static_cast<struct audio_fifo_itfe *>(fifo_itfe);
|
||||
return interface->p_fifo_reader->available();
|
||||
}
|
||||
|
||||
ssize_t fifo_available_to_write(void *fifo_itfe) {
|
||||
struct audio_fifo_itfe *interface = static_cast<struct audio_fifo_itfe *>(fifo_itfe);
|
||||
return interface->p_fifo_writer->available();
|
||||
}
|
||||
|
||||
ssize_t fifo_flush(void *fifo_itfe) {
|
||||
struct audio_fifo_itfe *interface = static_cast<struct audio_fifo_itfe *>(fifo_itfe);
|
||||
return interface->p_fifo_reader->flush();
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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 _AUDIO_FIFO_WRAPPER_H_
|
||||
#define _AUDIO_FIFO_WRAPPER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void *fifo_init(uint32_t bytes, bool reader_throttles_writer);
|
||||
void fifo_release(void *fifo_itfe);
|
||||
ssize_t fifo_read(void *fifo_itfe, void *buffer, size_t bytes);
|
||||
ssize_t fifo_write(void *fifo_itfe, void *buffer, size_t bytes);
|
||||
ssize_t fifo_available_to_read(void *fifo_itfe);
|
||||
ssize_t fifo_available_to_write(void *fifo_itfe);
|
||||
ssize_t fifo_flush(void *fifo_itfe);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* #ifndef _AUDIO_FIFO_WRAPPER_H_ */
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Copyright (C) 2020 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 "audio_hw_fir_filter"
|
||||
//#define LOG_NDEBUG 0
|
||||
|
||||
#include <assert.h>
|
||||
#include <audio_utils/primitives.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <log/log.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fir_filter.h"
|
||||
|
||||
#ifdef __ARM_NEON
|
||||
#include "arm_neon.h"
|
||||
#endif /* #ifdef __ARM_NEON */
|
||||
|
||||
fir_filter_t* fir_init(uint32_t channels, fir_filter_mode_t mode, uint32_t filter_length,
|
||||
uint32_t input_length, int16_t* coeffs) {
|
||||
if ((channels == 0) || (filter_length == 0) || (coeffs == NULL)) {
|
||||
ALOGE("%s: Invalid channel count, filter length or coefficient array.", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fir_filter_t* fir = (fir_filter_t*)calloc(1, sizeof(fir_filter_t));
|
||||
if (fir == NULL) {
|
||||
ALOGE("%s: Unable to allocate memory for fir_filter.", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fir->channels = channels;
|
||||
fir->filter_length = filter_length;
|
||||
/* Default: same filter coeffs for all channels */
|
||||
fir->mode = FIR_SINGLE_FILTER;
|
||||
uint32_t coeff_bytes = fir->filter_length * sizeof(int16_t);
|
||||
if (mode == FIR_PER_CHANNEL_FILTER) {
|
||||
fir->mode = FIR_PER_CHANNEL_FILTER;
|
||||
coeff_bytes = fir->filter_length * fir->channels * sizeof(int16_t);
|
||||
}
|
||||
|
||||
fir->coeffs = (int16_t*)malloc(coeff_bytes);
|
||||
if (fir->coeffs == NULL) {
|
||||
ALOGE("%s: Unable to allocate memory for FIR coeffs", __func__);
|
||||
goto exit_1;
|
||||
}
|
||||
memcpy(fir->coeffs, coeffs, coeff_bytes);
|
||||
|
||||
fir->buffer_size = (input_length + fir->filter_length) * fir->channels;
|
||||
fir->state = (int16_t*)malloc(fir->buffer_size * sizeof(int16_t));
|
||||
if (fir->state == NULL) {
|
||||
ALOGE("%s: Unable to allocate memory for FIR state", __func__);
|
||||
goto exit_2;
|
||||
}
|
||||
|
||||
#ifdef __ARM_NEON
|
||||
ALOGI("%s: Using ARM Neon", __func__);
|
||||
#endif /* #ifdef __ARM_NEON */
|
||||
|
||||
fir_reset(fir);
|
||||
return fir;
|
||||
|
||||
exit_2:
|
||||
free(fir->coeffs);
|
||||
exit_1:
|
||||
free(fir);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void fir_release(fir_filter_t* fir) {
|
||||
if (fir == NULL) {
|
||||
return;
|
||||
}
|
||||
free(fir->state);
|
||||
free(fir->coeffs);
|
||||
free(fir);
|
||||
}
|
||||
|
||||
void fir_reset(fir_filter_t* fir) {
|
||||
if (fir == NULL) {
|
||||
return;
|
||||
}
|
||||
memset(fir->state, 0, fir->buffer_size * sizeof(int16_t));
|
||||
}
|
||||
|
||||
void fir_process_interleaved(fir_filter_t* fir, int16_t* input, int16_t* output, uint32_t samples) {
|
||||
assert(fir != NULL);
|
||||
|
||||
int start_offset = (fir->filter_length - 1) * fir->channels;
|
||||
memcpy(&fir->state[start_offset], input, samples * fir->channels * sizeof(int16_t));
|
||||
// int ch;
|
||||
bool use_2nd_set_coeffs = (fir->channels > 1) && (fir->mode == FIR_PER_CHANNEL_FILTER);
|
||||
int16_t* p_coeff_A = &fir->coeffs[0];
|
||||
int16_t* p_coeff_B = use_2nd_set_coeffs ? &fir->coeffs[fir->filter_length] : &fir->coeffs[0];
|
||||
int16_t* p_output;
|
||||
for (int ch = 0; ch < fir->channels; ch += 2) {
|
||||
p_output = &output[ch];
|
||||
int offset = start_offset + ch;
|
||||
for (int s = 0; s < samples; s++) {
|
||||
int32_t acc_A = 0;
|
||||
int32_t acc_B = 0;
|
||||
|
||||
#ifdef __ARM_NEON
|
||||
int32x4_t acc_vec = vdupq_n_s32(0);
|
||||
for (int k = 0; k < fir->filter_length; k++, offset -= fir->channels) {
|
||||
int16x4_t coeff_vec = vdup_n_s16(p_coeff_A[k]);
|
||||
coeff_vec = vset_lane_s16(p_coeff_B[k], coeff_vec, 1);
|
||||
int16x4_t input_vec = vld1_s16(&fir->state[offset]);
|
||||
acc_vec = vmlal_s16(acc_vec, coeff_vec, input_vec);
|
||||
}
|
||||
acc_A = vgetq_lane_s32(acc_vec, 0);
|
||||
acc_B = vgetq_lane_s32(acc_vec, 1);
|
||||
#else
|
||||
for (int k = 0; k < fir->filter_length; k++, offset -= fir->channels) {
|
||||
int32_t input_A = (int32_t)(fir->state[offset]);
|
||||
int32_t coeff_A = (int32_t)(p_coeff_A[k]);
|
||||
int32_t input_B = (int32_t)(fir->state[offset + 1]);
|
||||
int32_t coeff_B = (int32_t)(p_coeff_B[k]);
|
||||
acc_A += (input_A * coeff_A);
|
||||
acc_B += (input_B * coeff_B);
|
||||
}
|
||||
#endif /* #ifdef __ARM_NEON */
|
||||
|
||||
*p_output = clamp16(acc_A >> 15);
|
||||
if (ch < fir->channels - 1) {
|
||||
*(p_output + 1) = clamp16(acc_B >> 15);
|
||||
}
|
||||
/* Move to next sample */
|
||||
p_output += fir->channels;
|
||||
offset += (fir->filter_length + 1) * fir->channels;
|
||||
}
|
||||
if (use_2nd_set_coeffs) {
|
||||
p_coeff_A += (fir->filter_length << 1);
|
||||
p_coeff_B += (fir->filter_length << 1);
|
||||
}
|
||||
}
|
||||
memmove(fir->state, &fir->state[samples * fir->channels],
|
||||
(fir->filter_length - 1) * fir->channels * sizeof(int16_t));
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (C) 2020 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 FIR_FILTER_H
|
||||
#define FIR_FILTER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum fir_filter_mode { FIR_SINGLE_FILTER = 0, FIR_PER_CHANNEL_FILTER } fir_filter_mode_t;
|
||||
|
||||
typedef struct fir_filter {
|
||||
fir_filter_mode_t mode;
|
||||
uint32_t channels;
|
||||
uint32_t filter_length;
|
||||
uint32_t buffer_size;
|
||||
int16_t* coeffs;
|
||||
int16_t* state;
|
||||
} fir_filter_t;
|
||||
|
||||
fir_filter_t* fir_init(uint32_t channels, fir_filter_mode_t mode, uint32_t filter_length,
|
||||
uint32_t input_length, int16_t* coeffs);
|
||||
void fir_release(fir_filter_t* fir);
|
||||
void fir_reset(fir_filter_t* fir);
|
||||
void fir_process_interleaved(fir_filter_t* fir, int16_t* input, int16_t* output, uint32_t samples);
|
||||
|
||||
#endif /* #ifndef FIR_FILTER_H */
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<mixer>
|
||||
<!-- FIXME: This should be moved to the appropriate path -->
|
||||
|
||||
<!-- Enable HDMITX Control from TDM B -->
|
||||
<ctl name="TOHDMITX Switch" value="1" />
|
||||
<ctl name="TOHDMITX I2S SRC" value="I2S B" />
|
||||
|
||||
<!-- PCM0 to TDMB -->
|
||||
<ctl name="TDMOUT_B SRC SEL" value="IN 0" />
|
||||
<ctl name="FRDDR_A SINK 1 SEL" value="OUT 1" />
|
||||
<ctl name="FRDDR_A SRC 1 EN Switch" value="1" />
|
||||
|
||||
<!-- PDM to PCM3 -->
|
||||
<ctl name="TODDR_A SRC SEL" value="IN 4" />
|
||||
|
||||
<!-- PDM to PCM1 (internal speaker) -->
|
||||
<ctl name="FRDDR_B SINK 1 SEL" value="OUT 0" />
|
||||
<ctl name="FRDDR_B SRC 1 EN Switch" value="1" />
|
||||
<ctl name="TDMOUT_A SRC SEL" value="IN 1" />
|
||||
</mixer>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<mixer>
|
||||
<!-- FIXME: This should be moved to the appropriate path -->
|
||||
|
||||
<!-- Enable HDMITX Control from TDM A -->
|
||||
<ctl name="TOHDMITX Switch" value="1" />
|
||||
<ctl name="TOHDMITX I2S SRC" value="I2S A" />
|
||||
|
||||
<!-- PCM0 to TDMB -->
|
||||
<ctl name="TDMOUT_A SRC SEL" value="IN 0" />
|
||||
<ctl name="FRDDR_A SINK 1 SEL" value="OUT 0" />
|
||||
<ctl name="FRDDR_A SRC 1 EN Switch" value="1" />
|
||||
</mixer>
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** Copyright 2020, 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.
|
||||
*/
|
||||
-->
|
||||
<resources>
|
||||
|
||||
<!-- For HDMI output only devices, volume is controlled by the HDMI sink. -->
|
||||
<bool name="config_useFixedVolume">true</bool>
|
||||
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,523 @@
|
|||
# FIR speaker EQ file for SEI-610
|
||||
# This filter attenuates 200-400Hz by 18dB,
|
||||
# and some 6dB notch attenuation at 2.25kHz, 3.8kHz, 6.6kHz.
|
||||
# Script to generate this file: https://drive.google.com/file/d/1_qvkZ8nU-c6tD6XrH80et2P12paardAz/view?usp=sharing
|
||||
|
||||
# Full frequency response here: https://b.corp.google.com/issues/159714063#comment3
|
||||
|
||||
# Each FIR coefficient is specified on one line (no leading spaces).
|
||||
# First line is 0th coefficient.
|
||||
# Values must be 16-bit integers. Currently, a max of 512 taps is supported.
|
||||
|
||||
18976
|
||||
9870
|
||||
-12520
|
||||
2452
|
||||
-766
|
||||
-1023
|
||||
1122
|
||||
-2509
|
||||
316
|
||||
-1464
|
||||
95
|
||||
-817
|
||||
-1191
|
||||
-1882
|
||||
-2299
|
||||
-1806
|
||||
-1180
|
||||
-310
|
||||
-68
|
||||
-303
|
||||
-957
|
||||
-1544
|
||||
-1738
|
||||
-1490
|
||||
-973
|
||||
-517
|
||||
-285
|
||||
-261
|
||||
-247
|
||||
-68
|
||||
305
|
||||
729
|
||||
983
|
||||
931
|
||||
612
|
||||
210
|
||||
-63
|
||||
-100
|
||||
48
|
||||
234
|
||||
313
|
||||
244
|
||||
99
|
||||
3
|
||||
36
|
||||
183
|
||||
350
|
||||
435
|
||||
398
|
||||
286
|
||||
191
|
||||
188
|
||||
282
|
||||
409
|
||||
483
|
||||
454
|
||||
336
|
||||
192
|
||||
92
|
||||
63
|
||||
83
|
||||
100
|
||||
73
|
||||
2
|
||||
-75
|
||||
-114
|
||||
-93
|
||||
-27
|
||||
41
|
||||
73
|
||||
55
|
||||
9
|
||||
-30
|
||||
-38
|
||||
-14
|
||||
18
|
||||
30
|
||||
9
|
||||
-34
|
||||
-78
|
||||
-100
|
||||
-94
|
||||
-75
|
||||
-62
|
||||
-68
|
||||
-91
|
||||
-116
|
||||
-124
|
||||
-109
|
||||
-79
|
||||
-50
|
||||
-35
|
||||
-37
|
||||
-47
|
||||
-53
|
||||
-48
|
||||
-33
|
||||
-19
|
||||
-14
|
||||
-22
|
||||
-38
|
||||
-51
|
||||
-55
|
||||
-49
|
||||
-38
|
||||
-31
|
||||
-32
|
||||
-38
|
||||
-45
|
||||
-45
|
||||
-38
|
||||
-26
|
||||
-17
|
||||
-14
|
||||
-16
|
||||
-21
|
||||
-23
|
||||
-21
|
||||
-16
|
||||
-12
|
||||
-13
|
||||
-17
|
||||
-25
|
||||
-30
|
||||
-32
|
||||
-31
|
||||
-29
|
||||
-28
|
||||
-30
|
||||
-33
|
||||
-36
|
||||
-37
|
||||
-35
|
||||
-32
|
||||
-30
|
||||
-31
|
||||
-33
|
||||
-36
|
||||
-38
|
||||
-38
|
||||
-37
|
||||
-37
|
||||
-38
|
||||
-40
|
||||
-43
|
||||
-46
|
||||
-47
|
||||
-47
|
||||
-46
|
||||
-46
|
||||
-47
|
||||
-49
|
||||
-50
|
||||
-50
|
||||
-50
|
||||
-49
|
||||
-48
|
||||
-49
|
||||
-50
|
||||
-51
|
||||
-51
|
||||
-51
|
||||
-51
|
||||
-51
|
||||
-51
|
||||
-52
|
||||
-53
|
||||
-54
|
||||
-54
|
||||
-54
|
||||
-54
|
||||
-54
|
||||
-54
|
||||
-55
|
||||
-55
|
||||
-55
|
||||
-54
|
||||
-54
|
||||
-54
|
||||
-54
|
||||
-54
|
||||
-55
|
||||
-55
|
||||
-55
|
||||
-55
|
||||
-55
|
||||
-55
|
||||
-55
|
||||
-56
|
||||
-56
|
||||
-56
|
||||
-56
|
||||
-56
|
||||
-56
|
||||
-56
|
||||
-56
|
||||
-56
|
||||
-56
|
||||
-56
|
||||
-55
|
||||
-55
|
||||
-55
|
||||
-56
|
||||
-56
|
||||
-56
|
||||
-56
|
||||
-55
|
||||
-55
|
||||
-55
|
||||
-56
|
||||
-56
|
||||
-56
|
||||
-55
|
||||
-55
|
||||
-55
|
||||
-55
|
||||
-55
|
||||
-55
|
||||
-55
|
||||
-55
|
||||
-55
|
||||
-54
|
||||
-54
|
||||
-54
|
||||
-54
|
||||
-54
|
||||
-54
|
||||
-54
|
||||
-53
|
||||
-53
|
||||
-53
|
||||
-53
|
||||
-53
|
||||
-53
|
||||
-52
|
||||
-52
|
||||
-52
|
||||
-52
|
||||
-51
|
||||
-51
|
||||
-51
|
||||
-51
|
||||
-50
|
||||
-50
|
||||
-50
|
||||
-50
|
||||
-49
|
||||
-49
|
||||
-49
|
||||
-48
|
||||
-48
|
||||
-48
|
||||
-48
|
||||
-47
|
||||
-47
|
||||
-47
|
||||
-46
|
||||
-46
|
||||
-46
|
||||
-45
|
||||
-45
|
||||
-45
|
||||
-44
|
||||
-44
|
||||
-44
|
||||
-43
|
||||
-43
|
||||
-43
|
||||
-42
|
||||
-42
|
||||
-41
|
||||
-41
|
||||
-41
|
||||
-40
|
||||
-40
|
||||
-40
|
||||
-39
|
||||
-39
|
||||
-38
|
||||
-38
|
||||
-38
|
||||
-37
|
||||
-37
|
||||
-36
|
||||
-36
|
||||
-36
|
||||
-35
|
||||
-35
|
||||
-34
|
||||
-34
|
||||
-33
|
||||
-33
|
||||
-33
|
||||
-32
|
||||
-32
|
||||
-31
|
||||
-31
|
||||
-31
|
||||
-30
|
||||
-30
|
||||
-29
|
||||
-29
|
||||
-28
|
||||
-28
|
||||
-27
|
||||
-27
|
||||
-27
|
||||
-26
|
||||
-26
|
||||
-25
|
||||
-25
|
||||
-24
|
||||
-24
|
||||
-24
|
||||
-23
|
||||
-23
|
||||
-22
|
||||
-22
|
||||
-21
|
||||
-21
|
||||
-20
|
||||
-20
|
||||
-20
|
||||
-19
|
||||
-19
|
||||
-18
|
||||
-18
|
||||
-17
|
||||
-17
|
||||
-17
|
||||
-16
|
||||
-16
|
||||
-15
|
||||
-15
|
||||
-14
|
||||
-14
|
||||
-14
|
||||
-13
|
||||
-13
|
||||
-12
|
||||
-12
|
||||
-11
|
||||
-11
|
||||
-11
|
||||
-10
|
||||
-10
|
||||
-9
|
||||
-9
|
||||
-9
|
||||
-8
|
||||
-8
|
||||
-7
|
||||
-7
|
||||
-7
|
||||
-6
|
||||
-6
|
||||
-5
|
||||
-5
|
||||
-5
|
||||
-4
|
||||
-4
|
||||
-3
|
||||
-3
|
||||
-3
|
||||
-2
|
||||
-2
|
||||
-1
|
||||
-1
|
||||
-1
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
1
|
||||
1
|
||||
1
|
||||
2
|
||||
2
|
||||
2
|
||||
3
|
||||
3
|
||||
3
|
||||
4
|
||||
4
|
||||
4
|
||||
5
|
||||
5
|
||||
5
|
||||
6
|
||||
6
|
||||
6
|
||||
7
|
||||
7
|
||||
7
|
||||
7
|
||||
8
|
||||
8
|
||||
8
|
||||
9
|
||||
9
|
||||
9
|
||||
9
|
||||
10
|
||||
10
|
||||
10
|
||||
10
|
||||
11
|
||||
11
|
||||
11
|
||||
11
|
||||
12
|
||||
12
|
||||
12
|
||||
12
|
||||
13
|
||||
13
|
||||
13
|
||||
13
|
||||
13
|
||||
14
|
||||
14
|
||||
14
|
||||
14
|
||||
14
|
||||
15
|
||||
15
|
||||
15
|
||||
15
|
||||
15
|
||||
16
|
||||
16
|
||||
16
|
||||
16
|
||||
16
|
||||
16
|
||||
17
|
||||
17
|
||||
17
|
||||
17
|
||||
17
|
||||
17
|
||||
17
|
||||
18
|
||||
18
|
||||
18
|
||||
18
|
||||
18
|
||||
18
|
||||
18
|
||||
18
|
||||
19
|
||||
19
|
||||
19
|
||||
19
|
||||
19
|
||||
19
|
||||
19
|
||||
19
|
||||
19
|
||||
19
|
||||
19
|
||||
20
|
||||
20
|
||||
20
|
||||
20
|
||||
20
|
||||
20
|
||||
20
|
||||
20
|
||||
20
|
||||
20
|
||||
20
|
||||
20
|
||||
20
|
||||
20
|
||||
20
|
||||
20
|
||||
20
|
||||
20
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
21
|
||||
20
|
||||
20
|
||||
20
|
||||
20
|
||||
20
|
||||
20
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
|
||||
//
|
||||
// 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.
|
||||
|
||||
package {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "device_amlogic_yukawa_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["device_amlogic_yukawa_license"],
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "bootctrl.yukawa",
|
||||
vendor: true,
|
||||
recovery_available: true,
|
||||
relative_install_path: "hw",
|
||||
|
||||
srcs: [
|
||||
"boot_control.cc",
|
||||
"bootloader_message.cpp"
|
||||
],
|
||||
|
||||
cflags: [
|
||||
"-DLOG_TAG=\"amlogic_bootcontrol\"",
|
||||
],
|
||||
|
||||
header_libs: ["libhardware_headers"],
|
||||
|
||||
static_libs: ["libfstab",],
|
||||
|
||||
shared_libs: [
|
||||
"liblog",
|
||||
"libcutils",
|
||||
"libbase",
|
||||
"libz"
|
||||
],
|
||||
}
|
||||
|
|
@ -0,0 +1,351 @@
|
|||
/*
|
||||
* Copyright (C) Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <log/log.h>
|
||||
#include <cutils/properties.h>
|
||||
#include <zlib.h>
|
||||
#include <hardware/boot_control.h>
|
||||
#include <bootloader_message.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#define BOOT_SLOT_PROP "ro.boot.slot_suffix"
|
||||
|
||||
struct BootControlPrivate {
|
||||
// The base struct needs to be first in the list.
|
||||
boot_control_module_t base;
|
||||
|
||||
// Whether this struct was initialized with data from the bootloader message
|
||||
// that doesn't change until next reboot.
|
||||
bool initialized;
|
||||
|
||||
// The path to the misc_device as reported in the fstab.
|
||||
const char* misc_device;
|
||||
|
||||
// The number of slots present on the device.
|
||||
unsigned int num_slots;
|
||||
|
||||
// The slot where we are running from.
|
||||
unsigned int current_slot;
|
||||
};
|
||||
|
||||
constexpr unsigned int kMaxNumSlots =
|
||||
sizeof(bootloader_control::slot_info) /
|
||||
sizeof(bootloader_control::slot_info[0]);
|
||||
|
||||
constexpr const char* kSlotSuffixes[kMaxNumSlots] = { "_a", "_b", "_c", "_d" };
|
||||
|
||||
// Return the little-endian representation of the CRC-32 of the first fields
|
||||
// in |boot_ctrl| up to the crc32_le field.
|
||||
static uint32_t GetBootloaderControlCRC(const bootloader_control* boot_ctrl) {
|
||||
return crc32(0, (const uint8_t*)boot_ctrl,
|
||||
offsetof(bootloader_control, crc32_le));
|
||||
}
|
||||
|
||||
static bool LoadBootloaderControl(const char* misc_device,
|
||||
bootloader_control* boot_ctrl) {
|
||||
std::string str_err;
|
||||
if (read_bootloader_control_from(boot_ctrl, misc_device, &str_err))
|
||||
return true;
|
||||
|
||||
ALOGE("%s", str_err.c_str());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool SaveBootloaderControl(const char* misc_device,
|
||||
bootloader_control* boot_ctrl) {
|
||||
boot_ctrl->crc32_le = GetBootloaderControlCRC(boot_ctrl);
|
||||
|
||||
std::string str_err;
|
||||
if (write_bootloader_control_to(boot_ctrl, misc_device, &str_err))
|
||||
return true;
|
||||
|
||||
ALOGE("%s", str_err.c_str());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return the index of the slot suffix passed or -1 if not a valid slot suffix.
|
||||
static int SlotSuffixToIndex(const char* suffix) {
|
||||
for (unsigned int slot = 0; slot < kMaxNumSlots; ++slot) {
|
||||
if (!strcmp(kSlotSuffixes[slot], suffix)) return slot;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool IsInitialized(const BootControlPrivate* module) {
|
||||
if (!module->initialized) {
|
||||
ALOGW("Module not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BootControlInit(boot_control_module_t* module) {
|
||||
struct BootControlPrivate* bootctrl_module =
|
||||
reinterpret_cast<BootControlPrivate*>(module);
|
||||
|
||||
if (bootctrl_module->initialized) return;
|
||||
|
||||
if (!module) {
|
||||
ALOGE("Invalid argument passed to %s", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
ALOGI("Init %s", module->common.name);
|
||||
|
||||
// Initialize the current_slot from the read-only property. If the property
|
||||
// was not set (from either the command line or the device tree), we can later
|
||||
// initialize it from the bootloader_control struct.
|
||||
char suffix_prop[PROPERTY_VALUE_MAX] = {0};
|
||||
property_get(BOOT_SLOT_PROP, suffix_prop, "");
|
||||
bootctrl_module->current_slot = SlotSuffixToIndex(suffix_prop);
|
||||
|
||||
std::string err;
|
||||
std::string device = get_bootloader_message_blk_device(&err);
|
||||
|
||||
bootloader_control boot_ctrl;
|
||||
if (!LoadBootloaderControl(device.c_str(), &boot_ctrl))
|
||||
ALOGE("Error loading metadata");
|
||||
|
||||
// Note that since there isn't a module unload function this memory is leaked.
|
||||
bootctrl_module->misc_device = strdup(device.c_str());
|
||||
uint32_t computed_crc32 = GetBootloaderControlCRC(&boot_ctrl);
|
||||
if (boot_ctrl.crc32_le != computed_crc32) {
|
||||
ALOGE("Invalid boot control found, expected CRC-32 0x%04X, "
|
||||
"but found 0x%04X. Should re-initializing A/B metadata.",
|
||||
computed_crc32, boot_ctrl.crc32_le);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string metadata_suffix = "_" + std::string(boot_ctrl.slot_suffix);
|
||||
if (SlotSuffixToIndex(metadata_suffix.c_str()) !=
|
||||
bootctrl_module->current_slot) {
|
||||
ALOGE("Kernel slot argument and A/B metadata do not match, "
|
||||
"%s=%s, slot metadata=%s", BOOT_SLOT_PROP, suffix_prop,
|
||||
boot_ctrl.slot_suffix);
|
||||
return;
|
||||
}
|
||||
|
||||
bootctrl_module->initialized = true;
|
||||
bootctrl_module->num_slots = boot_ctrl.nb_slot;
|
||||
|
||||
ALOGI("Current slot: %s(%d), number of slots: %d", boot_ctrl.slot_suffix,
|
||||
bootctrl_module->current_slot, bootctrl_module->num_slots);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int GetNumberSlots(boot_control_module_t* module) {
|
||||
BootControlPrivate* const bootctrl_module =
|
||||
reinterpret_cast<BootControlPrivate*>(module);
|
||||
|
||||
if (!IsInitialized(bootctrl_module)) return -1;
|
||||
|
||||
return bootctrl_module->num_slots;
|
||||
}
|
||||
|
||||
unsigned int GetCurrentSlot(boot_control_module_t* module) {
|
||||
BootControlPrivate* const bootctrl_module =
|
||||
reinterpret_cast<BootControlPrivate*>(module);
|
||||
|
||||
if (!IsInitialized(bootctrl_module)) return -1;
|
||||
|
||||
return bootctrl_module->current_slot;
|
||||
}
|
||||
|
||||
int IsSlotMarkedSuccessful(boot_control_module_t* module, unsigned int slot) {
|
||||
BootControlPrivate* const bootctrl_module =
|
||||
reinterpret_cast<BootControlPrivate*>(module);
|
||||
|
||||
if (!IsInitialized(bootctrl_module)) return -1;
|
||||
|
||||
if (slot >= kMaxNumSlots || slot >= bootctrl_module->num_slots) {
|
||||
// Invalid slot number.
|
||||
return -1;
|
||||
}
|
||||
|
||||
bootloader_control bootctrl;
|
||||
if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl))
|
||||
return -1;
|
||||
|
||||
return (bootctrl.slot_info[slot].successful_boot &&
|
||||
bootctrl.slot_info[slot].tries_remaining);
|
||||
}
|
||||
|
||||
int MarkBootSuccessful(boot_control_module_t* module) {
|
||||
BootControlPrivate* const bootctrl_module =
|
||||
reinterpret_cast<BootControlPrivate*>(module);
|
||||
|
||||
if (!IsInitialized(bootctrl_module)) return -1;
|
||||
|
||||
bootloader_control bootctrl;
|
||||
if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl))
|
||||
return -1;
|
||||
|
||||
bootctrl.slot_info[bootctrl_module->current_slot].successful_boot = 1;
|
||||
// tries_remaining == 0 means that the slot is not bootable anymore, make
|
||||
// sure we mark the current slot as bootable if it succeeds in the last
|
||||
// attempt.
|
||||
bootctrl.slot_info[bootctrl_module->current_slot].tries_remaining = 1;
|
||||
if (!SaveBootloaderControl(bootctrl_module->misc_device, &bootctrl))
|
||||
return -1;
|
||||
|
||||
ALOGI("Slot %d is marked as successfully booted",
|
||||
bootctrl_module->current_slot);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SetActiveBootSlot(boot_control_module_t* module, unsigned int slot) {
|
||||
BootControlPrivate* const bootctrl_module =
|
||||
reinterpret_cast<BootControlPrivate*>(module);
|
||||
|
||||
if (!IsInitialized(bootctrl_module))
|
||||
return -1;
|
||||
|
||||
if (slot >= kMaxNumSlots || slot >= bootctrl_module->num_slots) {
|
||||
// Invalid slot number.
|
||||
return -1;
|
||||
}
|
||||
|
||||
bootloader_control bootctrl;
|
||||
if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl))
|
||||
return -1;
|
||||
|
||||
// Set every other slot with a lower priority than the new "active" slot.
|
||||
const unsigned int kActivePriority = 15;
|
||||
const unsigned int kActiveTries = 6;
|
||||
for (unsigned int i = 0; i < bootctrl_module->num_slots; ++i) {
|
||||
if (i != slot) {
|
||||
if (bootctrl.slot_info[i].priority >= kActivePriority)
|
||||
bootctrl.slot_info[i].priority = kActivePriority - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Note that setting a slot as active doesn't change the successful bit.
|
||||
// The successful bit will only be changed by setSlotAsUnbootable().
|
||||
bootctrl.slot_info[slot].priority = kActivePriority;
|
||||
bootctrl.slot_info[slot].tries_remaining = kActiveTries;
|
||||
|
||||
// Setting the current slot as active is a way to revert the operation that
|
||||
// set *another* slot as active at the end of an updater. This is commonly
|
||||
// used to cancel the pending update. We should only reset the verity_corrpted
|
||||
// bit when attempting a new slot, otherwise the verity bit on the current
|
||||
// slot would be flip.
|
||||
if (slot != bootctrl_module->current_slot)
|
||||
bootctrl.slot_info[slot].verity_corrupted = 0;
|
||||
|
||||
if (!SaveBootloaderControl(bootctrl_module->misc_device, &bootctrl))
|
||||
return -1;
|
||||
|
||||
ALOGI("Slot %d is set as active", slot);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SetSlotAsUnbootable(boot_control_module_t* module, unsigned int slot) {
|
||||
BootControlPrivate* const bootctrl_module =
|
||||
reinterpret_cast<BootControlPrivate*>(module);
|
||||
|
||||
if (!IsInitialized(bootctrl_module))
|
||||
return -1;
|
||||
|
||||
if (slot >= kMaxNumSlots || slot >= bootctrl_module->num_slots) {
|
||||
// Invalid slot number.
|
||||
return -1;
|
||||
}
|
||||
|
||||
bootloader_control bootctrl;
|
||||
if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl))
|
||||
return -1;
|
||||
|
||||
// The only way to mark a slot as unbootable, regardless of the priority is to
|
||||
// set the tries_remaining to 0.
|
||||
bootctrl.slot_info[slot].successful_boot = 0;
|
||||
bootctrl.slot_info[slot].tries_remaining = 0;
|
||||
if (!SaveBootloaderControl(bootctrl_module->misc_device, &bootctrl))
|
||||
return -1;
|
||||
|
||||
ALOGI("Slot %d is marked as unbootable", slot);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int IsSlotBootable(struct boot_control_module* module, unsigned int slot) {
|
||||
BootControlPrivate* const bootctrl_module =
|
||||
reinterpret_cast<BootControlPrivate*>(module);
|
||||
|
||||
if (!IsInitialized(bootctrl_module)) return -1;
|
||||
|
||||
if (slot >= kMaxNumSlots || slot >= bootctrl_module->num_slots) {
|
||||
// Invalid slot number.
|
||||
return -1;
|
||||
}
|
||||
|
||||
bootloader_control bootctrl;
|
||||
if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl))
|
||||
return -1;
|
||||
|
||||
return bootctrl.slot_info[slot].tries_remaining;
|
||||
}
|
||||
|
||||
const char* GetSuffix(boot_control_module_t* module, unsigned int slot) {
|
||||
BootControlPrivate* const bootctrl_module =
|
||||
reinterpret_cast<BootControlPrivate*>(module);
|
||||
|
||||
if (!IsInitialized(bootctrl_module)) return NULL;
|
||||
|
||||
if (slot >= kMaxNumSlots || slot >= bootctrl_module->num_slots) return NULL;
|
||||
|
||||
return kSlotSuffixes[slot];
|
||||
}
|
||||
|
||||
static hw_module_methods_t boot_control_module_methods = {
|
||||
.open = NULL,
|
||||
};
|
||||
|
||||
BootControlPrivate HAL_MODULE_INFO_SYM = {
|
||||
.base = {
|
||||
.common ={
|
||||
.tag = HARDWARE_MODULE_TAG,
|
||||
.module_api_version = 1,
|
||||
.hal_api_version = 0,
|
||||
.id = BOOT_CONTROL_HARDWARE_MODULE_ID,
|
||||
.name = "Yukawa Boot control HAL",
|
||||
.author = "The Android Open Source Project",
|
||||
.methods = &boot_control_module_methods
|
||||
},
|
||||
|
||||
.init = BootControlInit,
|
||||
.getNumberSlots = GetNumberSlots,
|
||||
.getCurrentSlot = GetCurrentSlot,
|
||||
.markBootSuccessful = MarkBootSuccessful,
|
||||
.setActiveBootSlot = SetActiveBootSlot,
|
||||
.setSlotAsUnbootable = SetSlotAsUnbootable,
|
||||
.isSlotBootable = IsSlotBootable,
|
||||
.getSuffix = GetSuffix,
|
||||
.isSlotMarkedSuccessful = IsSlotMarkedSuccessful
|
||||
},
|
||||
|
||||
.initialized = false,
|
||||
.misc_device = nullptr,
|
||||
.num_slots = 0,
|
||||
.current_slot = 0
|
||||
};
|
||||
|
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* Copyright (C) 2016 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.
|
||||
*/
|
||||
|
||||
#include "bootloader_message.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <fstab/fstab.h>
|
||||
|
||||
using android::fs_mgr::Fstab;
|
||||
using android::fs_mgr::GetEntryForMountPoint;
|
||||
using android::fs_mgr::ReadDefaultFstab;
|
||||
|
||||
constexpr off_t kBootloaderControlOffset = offsetof(bootloader_message_ab, slot_suffix);
|
||||
|
||||
static std::string get_misc_blk_device(std::string* err) {
|
||||
Fstab fstab;
|
||||
if (!ReadDefaultFstab(&fstab)) {
|
||||
*err = "failed to read default fstab";
|
||||
return "";
|
||||
}
|
||||
auto record = GetEntryForMountPoint(&fstab, "/misc");
|
||||
if (record == nullptr) {
|
||||
*err = "failed to find /misc partition";
|
||||
return "";
|
||||
}
|
||||
return record->blk_device;
|
||||
}
|
||||
|
||||
// In recovery mode, recovery can get started and try to access the misc
|
||||
// device before the kernel has actually created it.
|
||||
static bool wait_for_device(const std::string& blk_device, std::string* err) {
|
||||
int tries = 0;
|
||||
int ret;
|
||||
err->clear();
|
||||
do {
|
||||
++tries;
|
||||
struct stat buf;
|
||||
ret = stat(blk_device.c_str(), &buf);
|
||||
if (ret == -1) {
|
||||
*err += android::base::StringPrintf("failed to stat %s try %d: %s\n",
|
||||
blk_device.c_str(), tries, strerror(errno));
|
||||
sleep(1);
|
||||
}
|
||||
} while (ret && tries < 10);
|
||||
|
||||
if (ret) {
|
||||
*err += android::base::StringPrintf("failed to stat %s\n", blk_device.c_str());
|
||||
}
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
static bool read_misc_partition(void* p, size_t size, const std::string& misc_blk_device,
|
||||
size_t offset, std::string* err) {
|
||||
if (!wait_for_device(misc_blk_device, err)) {
|
||||
return false;
|
||||
}
|
||||
android::base::unique_fd fd(open(misc_blk_device.c_str(), O_RDONLY));
|
||||
if (fd == -1) {
|
||||
*err = android::base::StringPrintf("failed to open %s: %s", misc_blk_device.c_str(),
|
||||
strerror(errno));
|
||||
return false;
|
||||
}
|
||||
if (lseek(fd, static_cast<off_t>(offset), SEEK_SET) != static_cast<off_t>(offset)) {
|
||||
*err = android::base::StringPrintf("failed to lseek %s: %s", misc_blk_device.c_str(),
|
||||
strerror(errno));
|
||||
return false;
|
||||
}
|
||||
if (!android::base::ReadFully(fd, p, size)) {
|
||||
*err = android::base::StringPrintf("failed to read %s: %s", misc_blk_device.c_str(),
|
||||
strerror(errno));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool write_misc_partition(const void* p, size_t size, const std::string& misc_blk_device,
|
||||
size_t offset, std::string* err) {
|
||||
android::base::unique_fd fd(open(misc_blk_device.c_str(), O_WRONLY));
|
||||
if (fd == -1) {
|
||||
*err = android::base::StringPrintf("failed to open %s: %s", misc_blk_device.c_str(),
|
||||
strerror(errno));
|
||||
return false;
|
||||
}
|
||||
if (lseek(fd, static_cast<off_t>(offset), SEEK_SET) != static_cast<off_t>(offset)) {
|
||||
*err = android::base::StringPrintf("failed to lseek %s: %s", misc_blk_device.c_str(),
|
||||
strerror(errno));
|
||||
return false;
|
||||
}
|
||||
if (!android::base::WriteFully(fd, p, size)) {
|
||||
*err = android::base::StringPrintf("failed to write %s: %s", misc_blk_device.c_str(),
|
||||
strerror(errno));
|
||||
return false;
|
||||
}
|
||||
if (fsync(fd) == -1) {
|
||||
*err = android::base::StringPrintf("failed to fsync %s: %s", misc_blk_device.c_str(),
|
||||
strerror(errno));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string get_bootloader_message_blk_device(std::string* err) {
|
||||
std::string misc_blk_device = get_misc_blk_device(err);
|
||||
if (misc_blk_device.empty()) return "";
|
||||
if (!wait_for_device(misc_blk_device, err)) return "";
|
||||
return misc_blk_device;
|
||||
}
|
||||
|
||||
bool read_bootloader_message_from(bootloader_message* boot, const std::string& misc_blk_device,
|
||||
std::string* err) {
|
||||
return read_misc_partition(boot, sizeof(*boot), misc_blk_device,
|
||||
BOOTLOADER_MESSAGE_OFFSET_IN_MISC, err);
|
||||
}
|
||||
|
||||
bool read_bootloader_message(bootloader_message* boot, std::string* err) {
|
||||
std::string misc_blk_device = get_misc_blk_device(err);
|
||||
if (misc_blk_device.empty()) {
|
||||
return false;
|
||||
}
|
||||
return read_bootloader_message_from(boot, misc_blk_device, err);
|
||||
}
|
||||
|
||||
bool read_bootloader_control_from(bootloader_control* boot_ctrl, const std::string& misc_blk_device,
|
||||
std::string* err) {
|
||||
return read_misc_partition(boot_ctrl, sizeof(bootloader_control), misc_blk_device,
|
||||
kBootloaderControlOffset, err);
|
||||
}
|
||||
|
||||
bool write_bootloader_message_to(const bootloader_message& boot, const std::string& misc_blk_device,
|
||||
std::string* err) {
|
||||
return write_misc_partition(&boot, sizeof(boot), misc_blk_device,
|
||||
BOOTLOADER_MESSAGE_OFFSET_IN_MISC, err);
|
||||
}
|
||||
|
||||
bool write_bootloader_message(const bootloader_message& boot, std::string* err) {
|
||||
std::string misc_blk_device = get_misc_blk_device(err);
|
||||
if (misc_blk_device.empty()) {
|
||||
return false;
|
||||
}
|
||||
return write_bootloader_message_to(boot, misc_blk_device, err);
|
||||
}
|
||||
|
||||
bool write_bootloader_control_to(const bootloader_control* boot_ctrl, const std::string& misc_blk_device,
|
||||
std::string* err) {
|
||||
return write_misc_partition(boot_ctrl, sizeof(bootloader_control), misc_blk_device,
|
||||
kBootloaderControlOffset, err);
|
||||
}
|
||||
|
||||
bool clear_bootloader_message(std::string* err) {
|
||||
bootloader_message boot = {};
|
||||
return write_bootloader_message(boot, err);
|
||||
}
|
||||
|
||||
bool write_bootloader_message(const std::vector<std::string>& options, std::string* err) {
|
||||
bootloader_message boot = {};
|
||||
update_bootloader_message_in_struct(&boot, options);
|
||||
|
||||
return write_bootloader_message(boot, err);
|
||||
}
|
||||
|
||||
bool update_bootloader_message(const std::vector<std::string>& options, std::string* err) {
|
||||
bootloader_message boot;
|
||||
if (!read_bootloader_message(&boot, err)) {
|
||||
return false;
|
||||
}
|
||||
update_bootloader_message_in_struct(&boot, options);
|
||||
|
||||
return write_bootloader_message(boot, err);
|
||||
}
|
||||
|
||||
bool update_bootloader_message_in_struct(bootloader_message* boot,
|
||||
const std::vector<std::string>& options) {
|
||||
if (!boot) return false;
|
||||
// Replace the command & recovery fields.
|
||||
memset(boot->command, 0, sizeof(boot->command));
|
||||
memset(boot->recovery, 0, sizeof(boot->recovery));
|
||||
|
||||
strlcpy(boot->command, "boot-recovery", sizeof(boot->command));
|
||||
strlcpy(boot->recovery, "recovery\n", sizeof(boot->recovery));
|
||||
for (const auto& s : options) {
|
||||
strlcat(boot->recovery, s.c_str(), sizeof(boot->recovery));
|
||||
if (s.back() != '\n') {
|
||||
strlcat(boot->recovery, "\n", sizeof(boot->recovery));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool write_reboot_bootloader(std::string* err) {
|
||||
bootloader_message boot;
|
||||
if (!read_bootloader_message(&boot, err)) {
|
||||
return false;
|
||||
}
|
||||
if (boot.command[0] != '\0') {
|
||||
*err = "Bootloader command pending.";
|
||||
return false;
|
||||
}
|
||||
strlcpy(boot.command, "bootonce-bootloader", sizeof(boot.command));
|
||||
return write_bootloader_message(boot, err);
|
||||
}
|
||||
|
||||
bool read_wipe_package(std::string* package_data, size_t size, std::string* err) {
|
||||
std::string misc_blk_device = get_misc_blk_device(err);
|
||||
if (misc_blk_device.empty()) {
|
||||
return false;
|
||||
}
|
||||
package_data->resize(size);
|
||||
return read_misc_partition(&(*package_data)[0], size, misc_blk_device,
|
||||
WIPE_PACKAGE_OFFSET_IN_MISC, err);
|
||||
}
|
||||
|
||||
bool write_wipe_package(const std::string& package_data, std::string* err) {
|
||||
std::string misc_blk_device = get_misc_blk_device(err);
|
||||
if (misc_blk_device.empty()) {
|
||||
return false;
|
||||
}
|
||||
return write_misc_partition(package_data.data(), package_data.size(), misc_blk_device,
|
||||
WIPE_PACKAGE_OFFSET_IN_MISC, err);
|
||||
}
|
||||
|
||||
extern "C" bool write_reboot_bootloader(void) {
|
||||
std::string err;
|
||||
return write_reboot_bootloader(&err);
|
||||
}
|
||||
|
||||
extern "C" bool write_bootloader_message(const char* options) {
|
||||
std::string err;
|
||||
return write_bootloader_message({options}, &err);
|
||||
}
|
||||
|
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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 _BOOTLOADER_MESSAGE_H
|
||||
#define _BOOTLOADER_MESSAGE_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Spaces used by misc partition are as below:
|
||||
// 0 - 2K For bootloader_message
|
||||
// 2K - 16K Used by Vendor's bootloader (the 2K - 4K range may be optionally used
|
||||
// as bootloader_message_ab struct)
|
||||
// 16K - 64K Used by uncrypt and recovery to store wipe_package for A/B devices
|
||||
// Note that these offsets are admitted by bootloader,recovery and uncrypt, so they
|
||||
// are not configurable without changing all of them.
|
||||
static const size_t BOOTLOADER_MESSAGE_OFFSET_IN_MISC = 0;
|
||||
static const size_t WIPE_PACKAGE_OFFSET_IN_MISC = 16 * 1024;
|
||||
|
||||
/* Bootloader Message (2-KiB)
|
||||
*
|
||||
* This structure describes the content of a block in flash
|
||||
* that is used for recovery and the bootloader to talk to
|
||||
* each other.
|
||||
*
|
||||
* The command field is updated by linux when it wants to
|
||||
* reboot into recovery or to update radio or bootloader firmware.
|
||||
* It is also updated by the bootloader when firmware update
|
||||
* is complete (to boot into recovery for any final cleanup)
|
||||
*
|
||||
* The status field was used by the bootloader after the completion
|
||||
* of an "update-radio" or "update-hboot" command, which has been
|
||||
* deprecated since Froyo.
|
||||
*
|
||||
* The recovery field is only written by linux and used
|
||||
* for the system to send a message to recovery or the
|
||||
* other way around.
|
||||
*
|
||||
* The stage field is written by packages which restart themselves
|
||||
* multiple times, so that the UI can reflect which invocation of the
|
||||
* package it is. If the value is of the format "#/#" (eg, "1/3"),
|
||||
* the UI will add a simple indicator of that status.
|
||||
*
|
||||
* We used to have slot_suffix field for A/B boot control metadata in
|
||||
* this struct, which gets unintentionally cleared by recovery or
|
||||
* uncrypt. Move it into struct bootloader_message_ab to avoid the
|
||||
* issue.
|
||||
*/
|
||||
struct bootloader_message {
|
||||
char command[32];
|
||||
char status[32];
|
||||
char recovery[768];
|
||||
|
||||
// The 'recovery' field used to be 1024 bytes. It has only ever
|
||||
// been used to store the recovery command line, so 768 bytes
|
||||
// should be plenty. We carve off the last 256 bytes to store the
|
||||
// stage string (for multistage packages) and possible future
|
||||
// expansion.
|
||||
char stage[32];
|
||||
|
||||
// The 'reserved' field used to be 224 bytes when it was initially
|
||||
// carved off from the 1024-byte recovery field. Bump it up to
|
||||
// 1184-byte so that the entire bootloader_message struct rounds up
|
||||
// to 2048-byte.
|
||||
char reserved[1184];
|
||||
};
|
||||
|
||||
/**
|
||||
* We must be cautious when changing the bootloader_message struct size,
|
||||
* because A/B-specific fields may end up with different offsets.
|
||||
*/
|
||||
#if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus)
|
||||
static_assert(sizeof(struct bootloader_message) == 2048,
|
||||
"struct bootloader_message size changes, which may break A/B devices");
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The A/B-specific bootloader message structure (4-KiB).
|
||||
*
|
||||
* We separate A/B boot control metadata from the regular bootloader
|
||||
* message struct and keep it here. Everything that's A/B-specific
|
||||
* stays after struct bootloader_message, which should be managed by
|
||||
* the A/B-bootloader or boot control HAL.
|
||||
*
|
||||
* The slot_suffix field is used for A/B implementations where the
|
||||
* bootloader does not set the androidboot.ro.boot.slot_suffix kernel
|
||||
* commandline parameter. This is used by fs_mgr to mount /system and
|
||||
* other partitions with the slotselect flag set in fstab. A/B
|
||||
* implementations are free to use all 32 bytes and may store private
|
||||
* data past the first NUL-byte in this field. It is encouraged, but
|
||||
* not mandatory, to use 'struct bootloader_control' described below.
|
||||
*
|
||||
* The update_channel field is used to store the Omaha update channel
|
||||
* if update_engine is compiled with Omaha support.
|
||||
*/
|
||||
struct bootloader_message_ab {
|
||||
struct bootloader_message message;
|
||||
char slot_suffix[32];
|
||||
char update_channel[128];
|
||||
|
||||
// Round up the entire struct to 4096-byte.
|
||||
char reserved[1888];
|
||||
};
|
||||
|
||||
/**
|
||||
* Be cautious about the struct size change, in case we put anything post
|
||||
* bootloader_message_ab struct (b/29159185).
|
||||
*/
|
||||
#if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus)
|
||||
static_assert(sizeof(struct bootloader_message_ab) == 4096,
|
||||
"struct bootloader_message_ab size changes");
|
||||
#endif
|
||||
|
||||
#define BOOT_CTRL_MAGIC 0x42414342 /* Bootloader Control AB */
|
||||
#define BOOT_CTRL_VERSION 1
|
||||
|
||||
struct slot_metadata {
|
||||
// Slot priority with 15 meaning highest priority, 1 lowest
|
||||
// priority and 0 the slot is unbootable.
|
||||
uint8_t priority : 4;
|
||||
// Number of times left attempting to boot this slot.
|
||||
uint8_t tries_remaining : 3;
|
||||
// 1 if this slot has booted successfully, 0 otherwise.
|
||||
uint8_t successful_boot : 1;
|
||||
// 1 if this slot is corrupted from a dm-verity corruption, 0
|
||||
// otherwise.
|
||||
uint8_t verity_corrupted : 1;
|
||||
// Reserved for further use.
|
||||
uint8_t reserved : 7;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Bootloader Control AB
|
||||
*
|
||||
* This struct can be used to manage A/B metadata. It is designed to
|
||||
* be put in the 'slot_suffix' field of the 'bootloader_message'
|
||||
* structure described above. It is encouraged to use the
|
||||
* 'bootloader_control' structure to store the A/B metadata, but not
|
||||
* mandatory.
|
||||
*/
|
||||
struct bootloader_control {
|
||||
// NUL terminated active slot suffix.
|
||||
char slot_suffix[4];
|
||||
// Bootloader Control AB magic number (see BOOT_CTRL_MAGIC).
|
||||
uint32_t magic;
|
||||
// Version of struct being used (see BOOT_CTRL_VERSION).
|
||||
uint8_t version;
|
||||
// Number of slots being managed.
|
||||
uint8_t nb_slot : 3;
|
||||
// Number of times left attempting to boot recovery.
|
||||
uint8_t recovery_tries_remaining : 3;
|
||||
// Ensure 4-bytes alignment for slot_info field.
|
||||
uint8_t reserved0[2];
|
||||
// Per-slot information. Up to 4 slots.
|
||||
struct slot_metadata slot_info[4];
|
||||
// Reserved for further use.
|
||||
uint8_t reserved1[8];
|
||||
// CRC32 of all 28 bytes preceding this field (little endian
|
||||
// format).
|
||||
uint32_t crc32_le;
|
||||
} __attribute__((packed));
|
||||
|
||||
#if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus)
|
||||
static_assert(sizeof(struct bootloader_control) ==
|
||||
sizeof(((struct bootloader_message_ab *)0)->slot_suffix),
|
||||
"struct bootloader_control has wrong size");
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Return the block device name for the bootloader message partition and waits
|
||||
// for the device for up to 10 seconds. In case of error returns the empty
|
||||
// string.
|
||||
std::string get_bootloader_message_blk_device(std::string* err);
|
||||
|
||||
// Read bootloader message into boot. Error message will be set in err.
|
||||
bool read_bootloader_message(bootloader_message* boot, std::string* err);
|
||||
|
||||
// Read bootloader message from the specified misc device into boot.
|
||||
bool read_bootloader_message_from(bootloader_message* boot, const std::string& misc_blk_device,
|
||||
std::string* err);
|
||||
|
||||
// Read bootloader control block from the specified misc device into boot_ctrl.
|
||||
bool read_bootloader_control_from(bootloader_control* boot_ctrl, const std::string& misc_blk_device,
|
||||
std::string* err);
|
||||
|
||||
// Write bootloader message to BCB.
|
||||
bool write_bootloader_message(const bootloader_message& boot, std::string* err);
|
||||
|
||||
// Write bootloader message to the specified BCB device.
|
||||
bool write_bootloader_message_to(const bootloader_message& boot,
|
||||
const std::string& misc_blk_device, std::string* err);
|
||||
|
||||
// Write bootloader message (boots into recovery with the options) to BCB. Will
|
||||
// set the command and recovery fields, and reset the rest.
|
||||
bool write_bootloader_message(const std::vector<std::string>& options, std::string* err);
|
||||
|
||||
// Write bootloader control block to the specified BCB device.
|
||||
bool write_bootloader_control_to(const bootloader_control* boot_ctrl, const std::string& misc_blk_device,
|
||||
std::string* err);
|
||||
|
||||
// Update bootloader message (boots into recovery with the options) to BCB. Will
|
||||
// only update the command and recovery fields.
|
||||
bool update_bootloader_message(const std::vector<std::string>& options, std::string* err);
|
||||
|
||||
// Update bootloader message (boots into recovery with the |options|) in |boot|. Will only update
|
||||
// the command and recovery fields.
|
||||
bool update_bootloader_message_in_struct(bootloader_message* boot,
|
||||
const std::vector<std::string>& options);
|
||||
|
||||
// Clear BCB.
|
||||
bool clear_bootloader_message(std::string* err);
|
||||
|
||||
// Writes the reboot-bootloader reboot reason to the bootloader_message.
|
||||
bool write_reboot_bootloader(std::string* err);
|
||||
|
||||
// Read the wipe package from BCB (from offset WIPE_PACKAGE_OFFSET_IN_MISC).
|
||||
bool read_wipe_package(std::string* package_data, size_t size, std::string* err);
|
||||
|
||||
// Write the wipe package into BCB (to offset WIPE_PACKAGE_OFFSET_IN_MISC).
|
||||
bool write_wipe_package(const std::string& package_data, std::string* err);
|
||||
|
||||
#else
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
// C Interface.
|
||||
bool write_bootloader_message(const char* options);
|
||||
bool write_reboot_bootloader(void);
|
||||
|
||||
#endif // ifdef __cplusplus
|
||||
|
||||
#endif // _BOOTLOADER_MESSAGE_H
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<ExternalCamera>
|
||||
<Provider>
|
||||
<ignore> <!-- Internal video devices to be ignored by external camera HAL -->
|
||||
<id>0</id>
|
||||
</ignore>
|
||||
</Provider>
|
||||
<Device>
|
||||
<MaxJpegBufferSize bytes="3145728"/>
|
||||
<NumVideoBuffers count="4"/>
|
||||
<NumStillBuffers count="2"/>
|
||||
<FpsList>
|
||||
<Limit width="640" height="480" fpsBound="30.0"/>
|
||||
<Limit width="1280" height="720" fpsBound="30.0"/>
|
||||
<Limit width="1920" height="1080" fpsBound="30.0"/>
|
||||
</FpsList>
|
||||
</Device>
|
||||
</ExternalCamera>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "device_amlogic_yukawa_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
// SPDX-license-identifier-GPL-2.0
|
||||
default_applicable_licenses: ["device_amlogic_yukawa_license"],
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "hwcomposer.drm_meson",
|
||||
defaults: ["hwcomposer.drm_defaults"],
|
||||
srcs: [
|
||||
":drm_hwcomposer_common",
|
||||
":drm_hwcomposer_platformmeson",
|
||||
],
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#
|
||||
# Copyright (C) 2016 ARM Limited. All rights reserved.
|
||||
#
|
||||
# Copyright (C) 2008 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.
|
||||
|
||||
$(info gralloc for juno)
|
||||
GRALLOC_FB_SWAP_RED_BLUE := 1
|
||||
GRALLOC_DEPTH := GRALLOC_32_BITS
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
#
|
||||
# Copyright (C) 2016-2017 ARM Limited. All rights reserved.
|
||||
#
|
||||
# Copyright (C) 2008 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)
|
||||
|
||||
# Include platform specific makefiles
|
||||
include $(if $(wildcard $(LOCAL_PATH)/Android.$(TARGET_BOARD_PLATFORM).mk), $(LOCAL_PATH)/Android.$(TARGET_BOARD_PLATFORM).mk,)
|
||||
|
||||
#
|
||||
# Static hardware defines
|
||||
#
|
||||
# These defines are used in case runtime detection does not find the
|
||||
# user-space driver to read out hardware capabilities
|
||||
|
||||
# GPU support for AFBC 1.0
|
||||
MALI_GPU_SUPPORT_AFBC_BASIC?=0
|
||||
# GPU support for AFBC 1.1 block split
|
||||
MALI_GPU_SUPPORT_AFBC_SPLITBLK?=0
|
||||
# GPU support for AFBC 1.1 wide block
|
||||
MALI_GPU_SUPPORT_AFBC_WIDEBLK?=0
|
||||
# GPU support for AFBC 1.2 tiled headers
|
||||
MALI_GPU_SUPPORT_AFBC_TILED_HEADERS?=0
|
||||
# GPU support YUV AFBC formats in wide block
|
||||
MALI_GPU_USE_YUV_AFBC_WIDEBLK?=0
|
||||
|
||||
# VPU version we support
|
||||
MALI_VIDEO_VERSION?=0
|
||||
# DPU version we support
|
||||
MALI_DISPLAY_VERSION?=0
|
||||
|
||||
#
|
||||
# Software behaviour defines
|
||||
#
|
||||
|
||||
# Gralloc1 support
|
||||
GRALLOC_USE_GRALLOC1_API?=0
|
||||
# Use ION DMA heap for all allocations. Default is system heap.
|
||||
GRALLOC_USE_ION_DMA_HEAP?=0
|
||||
# Use ION Compound heap for all allocations. Default is system heap.
|
||||
GRALLOC_USE_ION_COMPOUND_PAGE_HEAP?=0
|
||||
# Properly initializes an empty AFBC buffer
|
||||
GRALLOC_INIT_AFBC?=0
|
||||
# fbdev bitdepth to use
|
||||
GRALLOC_DEPTH?=GRALLOC_32_BITS
|
||||
# When enabled, forces display framebuffer format to BGRA_8888
|
||||
GRALLOC_FB_SWAP_RED_BLUE?=1
|
||||
# Disables the framebuffer HAL device. When a hwc impl is available.
|
||||
GRALLOC_DISABLE_FRAMEBUFFER_HAL?=0
|
||||
# When enabled, buffers will never be allocated with AFBC
|
||||
GRALLOC_ARM_NO_EXTERNAL_AFBC?=0
|
||||
# Minimum buffer dimensions in pixels when buffer will use AFBC
|
||||
GRALLOC_DISP_W?=0
|
||||
GRALLOC_DISP_H?=0
|
||||
# Vsync backend(not used)
|
||||
GRALLOC_VSYNC_BACKEND?=default
|
||||
|
||||
# HAL module implemenation, not prelinked and stored in
|
||||
# hw/<OVERLAY_HARDWARE_MODULE_ID>.<ro.product.board>.so
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
ifeq ($(TARGET_BOARD_PLATFORM), juno)
|
||||
ifeq ($(MALI_MMSS), 1)
|
||||
|
||||
# Use latest default MMSS build configuration if not already defined
|
||||
ifeq ($(MALI_DISPLAY_VERSION), 0)
|
||||
MALI_DISPLAY_VERSION = 650
|
||||
endif
|
||||
ifeq ($(MALI_VIDEO_VERSION), 0)
|
||||
MALI_VIDEO_VERSION = 550
|
||||
endif
|
||||
|
||||
GRALLOC_FB_SWAP_RED_BLUE = 0
|
||||
GRALLOC_USE_ION_DMA_HEAP = 1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_BOARD_PLATFORM), armboard_v7a)
|
||||
ifeq ($(GRALLOC_MALI_DP),true)
|
||||
GRALLOC_FB_SWAP_RED_BLUE = 0
|
||||
GRALLOC_DISABLE_FRAMEBUFFER_HAL=1
|
||||
MALI_DISPLAY_VERSION = 550
|
||||
GRALLOC_USE_ION_DMA_HEAP=1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(MALI_DISPLAY_VERSION), 0)
|
||||
#if Mali display is available, should disable framebuffer HAL
|
||||
GRALLOC_DISABLE_FRAMEBUFFER_HAL := 1
|
||||
#if Mali display is available, AFBC buffers should be initialised after allocation
|
||||
GRALLOC_INIT_AFBC := 1
|
||||
endif
|
||||
|
||||
ifeq ($(GRALLOC_USE_ION_DMA_HEAP), 1)
|
||||
ifeq ($(GRALLOC_USE_ION_COMPOUND_PAGE_HEAP), 1)
|
||||
$(error GRALLOC_USE_ION_DMA_HEAP and GRALLOC_USE_ION_COMPOUND_PAGE_HEAP can't be enabled at the same time)
|
||||
endif
|
||||
endif
|
||||
|
||||
PLATFORM_SDK_GREATER_THAN_24 := $(shell expr $(PLATFORM_SDK_VERSION) \> 24)
|
||||
|
||||
ifeq ($(PLATFORM_SDK_GREATER_THAN_24), 1)
|
||||
ifeq ($(GRALLOC_EXPERIMENTAL), 1)
|
||||
GRALLOC_USE_GRALLOC1_API := 1
|
||||
endif
|
||||
endif
|
||||
|
||||
LOCAL_C_INCLUDES := $(MALI_LOCAL_PATH) $(MALI_DDK_INCLUDES)
|
||||
|
||||
# General compilation flags
|
||||
LOCAL_CFLAGS := -Werror -DLOG_TAG=\"gralloc\" -DPLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION)
|
||||
|
||||
# Static hw flags
|
||||
LOCAL_CFLAGS += -DMALI_GPU_SUPPORT_AFBC_BASIC=$(MALI_GPU_SUPPORT_AFBC_BASIC)
|
||||
LOCAL_CFLAGS += -DMALI_GPU_SUPPORT_AFBC_SPLITBLK=$(MALI_GPU_SUPPORT_AFBC_SPLITBLK)
|
||||
LOCAL_CFLAGS += -DMALI_GPU_SUPPORT_AFBC_WIDEBLK=$(MALI_GPU_SUPPORT_AFBC_WIDEBLK)
|
||||
LOCAL_CFLAGS += -DMALI_GPU_USE_YUV_AFBC_WIDEBLK=$(MALI_GPU_USE_YUV_AFBC_WIDEBLK)
|
||||
LOCAL_CFLAGS += -DMALI_GPU_SUPPORT_AFBC_TILED_HEADERS=$(MALI_GPU_SUPPORT_AFBC_TILED_HEADERS)
|
||||
|
||||
LOCAL_CFLAGS += -DMALI_DISPLAY_VERSION=$(MALI_DISPLAY_VERSION)
|
||||
LOCAL_CFLAGS += -DMALI_VIDEO_VERSION=$(MALI_VIDEO_VERSION)
|
||||
|
||||
# Software behaviour flags
|
||||
LOCAL_CFLAGS += -DGRALLOC_USE_GRALLOC1_API=$(GRALLOC_USE_GRALLOC1_API)
|
||||
LOCAL_CFLAGS += -DGRALLOC_DISP_W=$(GRALLOC_DISP_W)
|
||||
LOCAL_CFLAGS += -DGRALLOC_DISP_H=$(GRALLOC_DISP_H)
|
||||
LOCAL_CFLAGS += -DDISABLE_FRAMEBUFFER_HAL=$(GRALLOC_DISABLE_FRAMEBUFFER_HAL)
|
||||
LOCAL_CFLAGS += -DGRALLOC_USE_ION_DMA_HEAP=$(GRALLOC_USE_ION_DMA_HEAP)
|
||||
LOCAL_CFLAGS += -DGRALLOC_USE_ION_COMPOUND_PAGE_HEAP=$(GRALLOC_USE_ION_COMPOUND_PAGE_HEAP)
|
||||
LOCAL_CFLAGS += -DGRALLOC_INIT_AFBC=$(GRALLOC_INIT_AFBC)
|
||||
LOCAL_CFLAGS += -D$(GRALLOC_DEPTH)
|
||||
LOCAL_CFLAGS += -DGRALLOC_FB_SWAP_RED_BLUE=$(GRALLOC_FB_SWAP_RED_BLUE)
|
||||
LOCAL_CFLAGS += -DGRALLOC_ARM_NO_EXTERNAL_AFBC=$(GRALLOC_ARM_NO_EXTERNAL_AFBC)
|
||||
LOCAL_CFLAGS += -DGRALLOC_LIBRARY_BUILD=1
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := libhardware liblog libcutils libGLESv1_CM libion libsync libutils
|
||||
|
||||
LOCAL_PRELINK_MODULE := false
|
||||
LOCAL_MODULE_RELATIVE_PATH := hw
|
||||
LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
|
||||
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
|
||||
LOCAL_MODULE := gralloc.yukawa
|
||||
LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-GPL-2.0
|
||||
LOCAL_LICENSE_CONDITIONS := notice restricted
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MULTILIB := both
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
mali_gralloc_module.cpp \
|
||||
framebuffer_device.cpp \
|
||||
gralloc_buffer_priv.cpp \
|
||||
gralloc_vsync_${GRALLOC_VSYNC_BACKEND}.cpp \
|
||||
mali_gralloc_bufferaccess.cpp \
|
||||
mali_gralloc_bufferallocation.cpp \
|
||||
mali_gralloc_bufferdescriptor.cpp \
|
||||
mali_gralloc_ion.cpp \
|
||||
mali_gralloc_formats.cpp \
|
||||
mali_gralloc_reference.cpp \
|
||||
mali_gralloc_debug.cpp
|
||||
|
||||
ifeq ($(GRALLOC_USE_GRALLOC1_API), 1)
|
||||
LOCAL_SRC_FILES += \
|
||||
mali_gralloc_public_interface.cpp \
|
||||
mali_gralloc_private_interface.cpp
|
||||
else
|
||||
LOCAL_SRC_FILES += legacy/alloc_device.cpp
|
||||
endif
|
||||
|
||||
LOCAL_MODULE_OWNER := arm
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#
|
||||
# Copyright (C) 2016 ARM Limited. All rights reserved.
|
||||
#
|
||||
# Copyright (C) 2008 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.
|
||||
|
||||
$(info gralloc for vexpress)
|
||||
GRALLOC_FB_SWAP_RED_BLUE := 0
|
||||
GRALLOC_DEPTH := GRALLOC_16_BITS
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
#
|
||||
# Copyright (C) 2016 ARM Limited. All rights reserved.
|
||||
#
|
||||
# Copyright (C) 2008 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.
|
||||
|
||||
# GPU support for AFBC 1.0
|
||||
MALI_GPU_SUPPORT_AFBC_BASIC=0
|
||||
# GPU support for AFBC 1.1 block split
|
||||
MALI_GPU_SUPPORT_AFBC_SPLITBLK=0
|
||||
# GPU support for AFBC 1.1 wide block
|
||||
MALI_GPU_SUPPORT_AFBC_WIDEBLK=0
|
||||
# GPU support for AFBC 1.2 tiled headers
|
||||
MALI_GPU_SUPPORT_AFBC_TILED_HEADERS=0
|
||||
# GPU support YUV AFBC formats in wide block
|
||||
MALI_GPU_USE_YUV_AFBC_WIDEBLK=0
|
||||
|
||||
#
|
||||
# Software behaviour defines
|
||||
#
|
||||
|
||||
# Gralloc1 support
|
||||
GRALLOC_USE_GRALLOC1_API=1
|
||||
# Use ION DMA heap for all allocations. Default is system heap.
|
||||
GRALLOC_USE_ION_DMA_HEAP=1
|
||||
# Use ION Compound heap for all allocations. Default is system heap.
|
||||
GRALLOC_USE_ION_COMPOUND_PAGE_HEAP=0
|
||||
# Properly initializes an empty AFBC buffer
|
||||
GRALLOC_INIT_AFBC=0
|
||||
# fbdev bitdepth to use
|
||||
GRALLOC_DEPTH=GRALLOC_32_BITS
|
||||
# When enabled, forces display framebuffer format to BGRA_8888
|
||||
GRALLOC_FB_SWAP_RED_BLUE=0
|
||||
# Disables the framebuffer HAL device. When a hwc impl is available.
|
||||
GRALLOC_DISABLE_FRAMEBUFFER_HAL=1
|
||||
# When enabled, buffers will never be allocated with AFBC
|
||||
GRALLOC_ARM_NO_EXTERNAL_AFBC=1
|
||||
# Minimum buffer dimensions in pixels when buffer will use AFBC
|
||||
GRALLOC_DISP_W=0
|
||||
GRALLOC_DISP_H=0
|
||||
# Vsync backend(not used)
|
||||
GRALLOC_VSYNC_BACKEND=default
|
||||
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
/*
|
||||
* DMABUF Heaps Userspace API
|
||||
*
|
||||
* Copyright (C) 2011 Google, Inc.
|
||||
* Copyright (C) 2019 Linaro Ltd.
|
||||
*/
|
||||
#ifndef _UAPI_LINUX_DMABUF_POOL_H
|
||||
#define _UAPI_LINUX_DMABUF_POOL_H
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/**
|
||||
* DOC: DMABUF Heaps Userspace API
|
||||
*/
|
||||
|
||||
/* Valid FD_FLAGS are O_CLOEXEC, O_RDONLY, O_WRONLY, O_RDWR */
|
||||
#define DMA_HEAP_VALID_FD_FLAGS (O_CLOEXEC | O_ACCMODE)
|
||||
|
||||
/* Currently no heap flags */
|
||||
#define DMA_HEAP_VALID_HEAP_FLAGS (0)
|
||||
|
||||
/**
|
||||
* struct dma_heap_allocation_data - metadata passed from userspace for
|
||||
* allocations
|
||||
* @len: size of the allocation
|
||||
* @fd: will be populated with a fd which provides the
|
||||
* handle to the allocated dma-buf
|
||||
* @fd_flags: file descriptor flags used when allocating
|
||||
* @heap_flags: flags passed to heap
|
||||
*
|
||||
* Provided by userspace as an argument to the ioctl
|
||||
*/
|
||||
struct dma_heap_allocation_data {
|
||||
__u64 len;
|
||||
__u32 fd;
|
||||
__u32 fd_flags;
|
||||
__u64 heap_flags;
|
||||
};
|
||||
|
||||
#define DMA_HEAP_IOC_MAGIC 'H'
|
||||
|
||||
/**
|
||||
* DOC: DMA_HEAP_IOCTL_ALLOC - allocate memory from pool
|
||||
*
|
||||
* Takes a dma_heap_allocation_data struct and returns it with the fd field
|
||||
* populated with the dmabuf handle of the allocation.
|
||||
*/
|
||||
#define DMA_HEAP_IOCTL_ALLOC _IOWR(DMA_HEAP_IOC_MAGIC, 0x0,\
|
||||
struct dma_heap_allocation_data)
|
||||
|
||||
#endif /* _UAPI_LINUX_DMABUF_POOL_H */
|
||||
|
|
@ -0,0 +1,650 @@
|
|||
/*
|
||||
* Copyright (C) 2010-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* Copyright (C) 2008 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/fb.h>
|
||||
|
||||
#include <log/log.h>
|
||||
#include <cutils/atomic.h>
|
||||
#include <hardware/hardware.h>
|
||||
#include <hardware/fb.h>
|
||||
|
||||
#include <GLES/gl.h>
|
||||
|
||||
#if GRALLOC_USE_GRALLOC1_API == 1
|
||||
#include <hardware/gralloc1.h>
|
||||
#else
|
||||
#include <hardware/gralloc.h>
|
||||
#endif
|
||||
|
||||
#include "mali_gralloc_module.h"
|
||||
#include "mali_gralloc_private_interface_types.h"
|
||||
#include "mali_gralloc_buffer.h"
|
||||
#include "gralloc_helper.h"
|
||||
#include "gralloc_vsync.h"
|
||||
#include "mali_gralloc_bufferaccess.h"
|
||||
#include "mali_gralloc_ion.h"
|
||||
|
||||
#define STANDARD_LINUX_SCREEN
|
||||
|
||||
// numbers of buffers for page flipping
|
||||
#define NUM_BUFFERS NUM_FB_BUFFERS
|
||||
|
||||
enum
|
||||
{
|
||||
PAGE_FLIP = 0x00000001,
|
||||
};
|
||||
|
||||
static int fb_set_swap_interval(struct framebuffer_device_t *dev, int interval)
|
||||
{
|
||||
if (interval < dev->minSwapInterval)
|
||||
{
|
||||
interval = dev->minSwapInterval;
|
||||
}
|
||||
else if (interval > dev->maxSwapInterval)
|
||||
{
|
||||
interval = dev->maxSwapInterval;
|
||||
}
|
||||
|
||||
private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
|
||||
m->swapInterval = interval;
|
||||
|
||||
if (0 == interval)
|
||||
{
|
||||
gralloc_vsync_disable(dev);
|
||||
}
|
||||
else
|
||||
{
|
||||
gralloc_vsync_enable(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fb_post(struct framebuffer_device_t *dev, buffer_handle_t buffer)
|
||||
{
|
||||
if (private_handle_t::validate(buffer) < 0)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(buffer);
|
||||
private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module);
|
||||
|
||||
if (m->currentBuffer)
|
||||
{
|
||||
mali_gralloc_unlock(m, m->currentBuffer);
|
||||
m->currentBuffer = 0;
|
||||
}
|
||||
|
||||
if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)
|
||||
{
|
||||
mali_gralloc_lock(m, buffer, private_module_t::PRIV_USAGE_LOCKED_FOR_POST, -1, -1, -1, -1, NULL);
|
||||
|
||||
int interrupt;
|
||||
m->info.activate = FB_ACTIVATE_VBL;
|
||||
m->info.yoffset = hnd->offset / m->finfo.line_length;
|
||||
|
||||
#ifdef STANDARD_LINUX_SCREEN
|
||||
|
||||
if (ioctl(m->framebuffer->fd, FBIOPAN_DISPLAY, &m->info) == -1)
|
||||
{
|
||||
AERR("FBIOPAN_DISPLAY failed for fd: %d", m->framebuffer->fd);
|
||||
mali_gralloc_unlock(m, buffer);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
#else /*Standard Android way*/
|
||||
|
||||
if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1)
|
||||
{
|
||||
AERR("FBIOPUT_VSCREENINFO failed for fd: %d", m->framebuffer->fd);
|
||||
mali_gralloc_unlock(m, buffer);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (0 != gralloc_wait_for_vsync(dev))
|
||||
{
|
||||
AERR("Gralloc wait for vsync failed for fd: %d", m->framebuffer->fd);
|
||||
mali_gralloc_unlock(m, buffer);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
m->currentBuffer = buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
void *fb_vaddr;
|
||||
void *buffer_vaddr;
|
||||
|
||||
mali_gralloc_lock(m, m->framebuffer, GRALLOC_USAGE_SW_WRITE_RARELY, -1, -1, -1, -1, &fb_vaddr);
|
||||
|
||||
mali_gralloc_lock(m, buffer, GRALLOC_USAGE_SW_READ_RARELY, -1, -1, -1, -1, &buffer_vaddr);
|
||||
|
||||
// If buffer's alignment match framebuffer alignment we can do a direct copy.
|
||||
// If not we must fallback to do an aligned copy of each line.
|
||||
if (hnd->byte_stride == (int)m->finfo.line_length)
|
||||
{
|
||||
memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres);
|
||||
}
|
||||
else
|
||||
{
|
||||
uintptr_t fb_offset = 0;
|
||||
uintptr_t buffer_offset = 0;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < m->info.yres; i++)
|
||||
{
|
||||
memcpy((void *)((uintptr_t)fb_vaddr + fb_offset), (void *)((uintptr_t)buffer_vaddr + buffer_offset),
|
||||
m->finfo.line_length);
|
||||
|
||||
fb_offset += m->finfo.line_length;
|
||||
buffer_offset += hnd->byte_stride;
|
||||
}
|
||||
}
|
||||
|
||||
mali_gralloc_unlock(m, buffer);
|
||||
mali_gralloc_unlock(m, m->framebuffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_frame_buffer_locked(struct private_module_t *module)
|
||||
{
|
||||
if (module->framebuffer)
|
||||
{
|
||||
return 0; // Nothing to do, already initialized
|
||||
}
|
||||
|
||||
char const *const device_template[] = { "/dev/graphics/fb%u", "/dev/fb%u", NULL };
|
||||
|
||||
int fd = -1;
|
||||
int i = 0;
|
||||
char name[64];
|
||||
|
||||
while ((fd == -1) && device_template[i])
|
||||
{
|
||||
snprintf(name, 64, device_template[i], 0);
|
||||
fd = open(name, O_RDWR, 0);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
|
||||
struct fb_fix_screeninfo finfo;
|
||||
|
||||
if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
|
||||
struct fb_var_screeninfo info;
|
||||
|
||||
if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
|
||||
info.reserved[0] = 0;
|
||||
info.reserved[1] = 0;
|
||||
info.reserved[2] = 0;
|
||||
info.xoffset = 0;
|
||||
info.yoffset = 0;
|
||||
info.activate = FB_ACTIVATE_NOW;
|
||||
|
||||
#ifdef GRALLOC_16_BITS
|
||||
/*
|
||||
* Explicitly request 5/6/5
|
||||
*/
|
||||
info.bits_per_pixel = 16;
|
||||
info.red.offset = 11;
|
||||
info.red.length = 5;
|
||||
info.green.offset = 5;
|
||||
info.green.length = 6;
|
||||
info.blue.offset = 0;
|
||||
info.blue.length = 5;
|
||||
info.transp.offset = 0;
|
||||
info.transp.length = 0;
|
||||
#else
|
||||
/*
|
||||
* Explicitly request 8/8/8
|
||||
*/
|
||||
info.bits_per_pixel = 32;
|
||||
info.red.offset = 16;
|
||||
info.red.length = 8;
|
||||
info.green.offset = 8;
|
||||
info.green.length = 8;
|
||||
info.blue.offset = 0;
|
||||
info.blue.length = 8;
|
||||
info.transp.offset = 0;
|
||||
info.transp.length = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Request NUM_BUFFERS screens (at lest 2 for page flipping)
|
||||
*/
|
||||
info.yres_virtual = info.yres * NUM_BUFFERS;
|
||||
|
||||
uint32_t flags = PAGE_FLIP;
|
||||
|
||||
if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1)
|
||||
{
|
||||
info.yres_virtual = info.yres;
|
||||
flags &= ~PAGE_FLIP;
|
||||
AWAR("FBIOPUT_VSCREENINFO failed, page flipping not supported fd: %d", fd);
|
||||
}
|
||||
|
||||
if (info.yres_virtual < info.yres * 2)
|
||||
{
|
||||
// we need at least 2 for page-flipping
|
||||
info.yres_virtual = info.yres;
|
||||
flags &= ~PAGE_FLIP;
|
||||
AWAR("page flipping not supported (yres_virtual=%d, requested=%d)", info.yres_virtual, info.yres * 2);
|
||||
}
|
||||
|
||||
if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
|
||||
int refreshRate = 0;
|
||||
|
||||
if (info.pixclock > 0)
|
||||
{
|
||||
refreshRate =
|
||||
1000000000000000LLU / (uint64_t(info.upper_margin + info.lower_margin + info.yres + info.hsync_len) *
|
||||
(info.left_margin + info.right_margin + info.xres + info.vsync_len) * info.pixclock);
|
||||
}
|
||||
else
|
||||
{
|
||||
AWAR("fbdev pixclock is zero for fd: %d", fd);
|
||||
}
|
||||
|
||||
if (refreshRate == 0)
|
||||
{
|
||||
refreshRate = 60 * 1000; // 60 Hz
|
||||
}
|
||||
|
||||
if (int(info.width) <= 0 || int(info.height) <= 0)
|
||||
{
|
||||
// the driver doesn't return that information
|
||||
// default to 160 dpi
|
||||
info.width = ((info.xres * 25.4f) / 160.0f + 0.5f);
|
||||
info.height = ((info.yres * 25.4f) / 160.0f + 0.5f);
|
||||
}
|
||||
|
||||
float xdpi = (info.xres * 25.4f) / info.width;
|
||||
float ydpi = (info.yres * 25.4f) / info.height;
|
||||
float fps = refreshRate / 1000.0f;
|
||||
|
||||
AINF("using (fd=%d)\n"
|
||||
"id = %s\n"
|
||||
"xres = %d px\n"
|
||||
"yres = %d px\n"
|
||||
"xres_virtual = %d px\n"
|
||||
"yres_virtual = %d px\n"
|
||||
"bpp = %d\n"
|
||||
"r = %2u:%u\n"
|
||||
"g = %2u:%u\n"
|
||||
"b = %2u:%u\n",
|
||||
fd, finfo.id, info.xres, info.yres, info.xres_virtual, info.yres_virtual, info.bits_per_pixel, info.red.offset,
|
||||
info.red.length, info.green.offset, info.green.length, info.blue.offset, info.blue.length);
|
||||
|
||||
AINF("width = %d mm (%f dpi)\n"
|
||||
"height = %d mm (%f dpi)\n"
|
||||
"refresh rate = %.2f Hz\n",
|
||||
info.width, xdpi, info.height, ydpi, fps);
|
||||
|
||||
if (0 == strncmp(finfo.id, "CLCD FB", 7))
|
||||
{
|
||||
module->dpy_type = MALI_DPY_TYPE_CLCD;
|
||||
}
|
||||
else if (0 == strncmp(finfo.id, "ARM Mali HDLCD", 14))
|
||||
{
|
||||
module->dpy_type = MALI_DPY_TYPE_HDLCD;
|
||||
}
|
||||
else if (0 == strncmp(finfo.id, "ARM HDLCD Control", 16))
|
||||
{
|
||||
module->dpy_type = MALI_DPY_TYPE_HDLCD;
|
||||
}
|
||||
else
|
||||
{
|
||||
module->dpy_type = MALI_DPY_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (finfo.smem_len <= 0)
|
||||
{
|
||||
return -errno;
|
||||
}
|
||||
|
||||
module->flags = flags;
|
||||
module->info = info;
|
||||
module->finfo = finfo;
|
||||
module->xdpi = xdpi;
|
||||
module->ydpi = ydpi;
|
||||
module->fps = fps;
|
||||
module->swapInterval = 1;
|
||||
|
||||
/*
|
||||
* map the framebuffer
|
||||
*/
|
||||
size_t fbSize = round_up_to_page_size(finfo.line_length * info.yres_virtual);
|
||||
void *vaddr = mmap(0, fbSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
|
||||
if (vaddr == MAP_FAILED)
|
||||
{
|
||||
AERR("Error mapping the framebuffer (%s)", strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
memset(vaddr, 0, fbSize);
|
||||
|
||||
// Create a "fake" buffer object for the entire frame buffer memory, and store it in the module
|
||||
module->framebuffer = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, fbSize, vaddr,
|
||||
GRALLOC_USAGE_HW_FB, GRALLOC_USAGE_HW_FB, dup(fd), 0);
|
||||
|
||||
module->numBuffers = info.yres_virtual / info.yres;
|
||||
module->bufferMask = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_frame_buffer(struct private_module_t *module)
|
||||
{
|
||||
pthread_mutex_lock(&module->lock);
|
||||
int err = init_frame_buffer_locked(module);
|
||||
pthread_mutex_unlock(&module->lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int fb_close(struct hw_device_t *device)
|
||||
{
|
||||
framebuffer_device_t *dev = reinterpret_cast<framebuffer_device_t *>(device);
|
||||
|
||||
if (dev)
|
||||
{
|
||||
free(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fb_alloc_framebuffer_dmabuf(private_module_t *m, private_handle_t *hnd)
|
||||
{
|
||||
struct fb_dmabuf_export fb_dma_buf;
|
||||
int res;
|
||||
res = ioctl(m->framebuffer->fd, FBIOGET_DMABUF, &fb_dma_buf);
|
||||
|
||||
if (res == 0)
|
||||
{
|
||||
hnd->share_fd = fb_dma_buf.fd;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
AINF("FBIOGET_DMABUF ioctl failed(%d). See gralloc_priv.h and the integration manual for vendor framebuffer "
|
||||
"integration",
|
||||
res);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int fb_alloc_from_ion_module(mali_gralloc_module *m, size_t buffer_size, uint64_t consumer_usage,
|
||||
uint64_t producer_usage, buffer_handle_t *pHandle)
|
||||
{
|
||||
buffer_descriptor_t fb_buffer_descriptor;
|
||||
gralloc_buffer_descriptor_t gralloc_buffer_descriptor[1];
|
||||
bool shared = false;
|
||||
int err = 0;
|
||||
|
||||
fb_buffer_descriptor.size = buffer_size;
|
||||
fb_buffer_descriptor.consumer_usage = consumer_usage;
|
||||
fb_buffer_descriptor.producer_usage = producer_usage;
|
||||
gralloc_buffer_descriptor[0] = (gralloc_buffer_descriptor_t)(&fb_buffer_descriptor);
|
||||
|
||||
err = mali_gralloc_ion_allocate(m, gralloc_buffer_descriptor, 1, pHandle, &shared);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int fb_alloc_framebuffer_locked(mali_gralloc_module *m, uint64_t consumer_usage, uint64_t producer_usage,
|
||||
buffer_handle_t *pHandle, int *stride, int *byte_stride)
|
||||
{
|
||||
// allocate the framebuffer
|
||||
if (m->framebuffer == NULL)
|
||||
{
|
||||
// initialize the framebuffer, the framebuffer is mapped once and forever.
|
||||
int err = init_frame_buffer_locked(m);
|
||||
|
||||
if (err < 0)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t bufferMask = m->bufferMask;
|
||||
const uint32_t numBuffers = m->numBuffers;
|
||||
/* framebufferSize is used for allocating the handle to the framebuffer and refers
|
||||
* to the size of the actual framebuffer.
|
||||
* alignedFramebufferSize is used for allocating a possible internal buffer and
|
||||
* thus need to consider internal alignment requirements. */
|
||||
const size_t framebufferSize = m->finfo.line_length * m->info.yres;
|
||||
const size_t alignedFramebufferSize = GRALLOC_ALIGN(m->finfo.line_length, 64) * m->info.yres;
|
||||
|
||||
*stride = m->info.xres;
|
||||
|
||||
if (numBuffers == 1)
|
||||
{
|
||||
// If we have only one buffer, we never use page-flipping. Instead,
|
||||
// we return a regular buffer which will be memcpy'ed to the main
|
||||
// screen when post is called.
|
||||
uint64_t newConsumerUsage = (consumer_usage & ~GRALLOC_USAGE_HW_FB);
|
||||
uint64_t newProducerUsage = (producer_usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
|
||||
AWAR("fallback to single buffering. Virtual Y-res too small %d", m->info.yres);
|
||||
*byte_stride = GRALLOC_ALIGN(m->finfo.line_length, 64);
|
||||
return fb_alloc_from_ion_module(m, alignedFramebufferSize, newConsumerUsage, newProducerUsage, pHandle);
|
||||
}
|
||||
|
||||
if (bufferMask >= ((1LU << numBuffers) - 1))
|
||||
{
|
||||
// We ran out of buffers, reset bufferMask
|
||||
bufferMask = 0;
|
||||
m->bufferMask = 0;
|
||||
}
|
||||
|
||||
uintptr_t framebufferVaddr = (uintptr_t)m->framebuffer->base;
|
||||
|
||||
// find a free slot
|
||||
for (uint32_t i = 0; i < numBuffers; i++)
|
||||
{
|
||||
if ((bufferMask & (1LU << i)) == 0)
|
||||
{
|
||||
m->bufferMask |= (1LU << i);
|
||||
break;
|
||||
}
|
||||
|
||||
framebufferVaddr += framebufferSize;
|
||||
}
|
||||
|
||||
// The entire framebuffer memory is already mapped, now create a buffer object for parts of this memory
|
||||
private_handle_t *hnd = new private_handle_t(
|
||||
private_handle_t::PRIV_FLAGS_FRAMEBUFFER, framebufferSize, (void *)framebufferVaddr, consumer_usage,
|
||||
producer_usage, dup(m->framebuffer->fd), (framebufferVaddr - (uintptr_t)m->framebuffer->base));
|
||||
|
||||
/*
|
||||
* Perform allocator specific actions. If these fail we fall back to a regular buffer
|
||||
* which will be memcpy'ed to the main screen when fb_post is called.
|
||||
*/
|
||||
if (fb_alloc_framebuffer_dmabuf(m, hnd) == -1)
|
||||
{
|
||||
delete hnd;
|
||||
uint64_t newConsumerUsage = (consumer_usage & ~GRALLOC_USAGE_HW_FB);
|
||||
uint64_t newProducerUsage = (producer_usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
|
||||
AERR("Fallback to single buffering. Unable to map framebuffer memory to handle:%p", hnd);
|
||||
*byte_stride = GRALLOC_ALIGN(m->finfo.line_length, 64);
|
||||
return fb_alloc_from_ion_module(m, alignedFramebufferSize, newConsumerUsage, newProducerUsage, pHandle);
|
||||
}
|
||||
|
||||
*pHandle = hnd;
|
||||
*byte_stride = m->finfo.line_length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fb_alloc_framebuffer(mali_gralloc_module *m, uint64_t consumer_usage, uint64_t producer_usage,
|
||||
buffer_handle_t *pHandle, int *stride, int *byte_stride)
|
||||
{
|
||||
pthread_mutex_lock(&m->lock);
|
||||
int err = fb_alloc_framebuffer_locked(m, consumer_usage, producer_usage, pHandle, stride, byte_stride);
|
||||
pthread_mutex_unlock(&m->lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
int compositionComplete(struct framebuffer_device_t *dev)
|
||||
{
|
||||
GRALLOC_UNUSED(dev);
|
||||
|
||||
/* By doing a finish here we force the GL driver to start rendering
|
||||
all the drawcalls up to this point, and to wait for the rendering to be complete.*/
|
||||
glFinish();
|
||||
/* The rendering of the backbuffer is now completed.
|
||||
When SurfaceFlinger later does a call to eglSwapBuffer(), the swap will be done
|
||||
synchronously in the same thread, and not asynchronoulsy in a background thread later.
|
||||
The SurfaceFlinger requires this behaviour since it releases the lock on all the
|
||||
SourceBuffers (Layers) after the compositionComplete() function returns.
|
||||
However this "bad" behaviour by SurfaceFlinger should not affect performance,
|
||||
since the Applications that render the SourceBuffers (Layers) still get the
|
||||
full renderpipeline using asynchronous rendering. So they perform at maximum speed,
|
||||
and because of their complexity compared to the Surface flinger jobs, the Surface flinger
|
||||
is normally faster even if it does everyhing synchronous and serial.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
int framebuffer_device_open(hw_module_t const *module, const char *name, hw_device_t **device)
|
||||
{
|
||||
int status = -EINVAL;
|
||||
|
||||
GRALLOC_UNUSED(name);
|
||||
|
||||
#if GRALLOC_USE_GRALLOC1_API == 1
|
||||
gralloc1_device_t *gralloc_device;
|
||||
#else
|
||||
alloc_device_t *gralloc_device;
|
||||
#endif
|
||||
|
||||
#if DISABLE_FRAMEBUFFER_HAL == 1
|
||||
AERR("Framebuffer HAL not support/disabled %s",
|
||||
#ifdef MALI_DISPLAY_VERSION
|
||||
"with MALI display enable");
|
||||
#else
|
||||
"");
|
||||
#endif
|
||||
return -ENODEV;
|
||||
#endif
|
||||
|
||||
#if GRALLOC_USE_GRALLOC1_API == 1
|
||||
status = gralloc1_open(module, &gralloc_device);
|
||||
#else
|
||||
status = gralloc_open(module, &gralloc_device);
|
||||
#endif
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
private_module_t *m = (private_module_t *)module;
|
||||
status = init_frame_buffer(m);
|
||||
|
||||
/* malloc is used instead of 'new' to instantiate the struct framebuffer_device_t
|
||||
* C++11 spec specifies that if a class/struct has a const member,default constructor
|
||||
* is deleted. So, if 'new' is used to instantiate the class/struct, it will throw
|
||||
* error complaining about deleted constructor. Even if the struct is wrapped in a class
|
||||
* it will still try to use the base class constructor to initialize the members, resulting
|
||||
* in error 'deleted constructor'.
|
||||
* This leaves two options
|
||||
* Option 1: initialize the const members at the instantiation time. With {value1, value2 ..}
|
||||
* Which relies on the order of the members, and if members are reordered or a new member is introduced
|
||||
* it will end up assiging wrong value to members. Designated assignment as well has been removed in C++11
|
||||
* Option 2: use malloc instead of 'new' to allocate the class/struct and initialize the members in code.
|
||||
* This is the only maintainable option available.
|
||||
*/
|
||||
|
||||
framebuffer_device_t *dev = reinterpret_cast<framebuffer_device_t *>(malloc(sizeof(framebuffer_device_t)));
|
||||
|
||||
/* if either or both of init_frame_buffer() and malloc failed */
|
||||
if ((status < 0) || (!dev))
|
||||
{
|
||||
#if GRALLOC_USE_GRALLOC1_API == 1
|
||||
gralloc1_close(gralloc_device);
|
||||
#else
|
||||
gralloc_close(gralloc_device);
|
||||
#endif
|
||||
(!dev) ? (void)(status = -ENOMEM) : free(dev);
|
||||
return status;
|
||||
}
|
||||
|
||||
memset(dev, 0, sizeof(*dev));
|
||||
|
||||
/* initialize the procs */
|
||||
dev->common.tag = HARDWARE_DEVICE_TAG;
|
||||
dev->common.version = 0;
|
||||
dev->common.module = const_cast<hw_module_t *>(module);
|
||||
dev->common.close = fb_close;
|
||||
dev->setSwapInterval = fb_set_swap_interval;
|
||||
dev->post = fb_post;
|
||||
dev->setUpdateRect = 0;
|
||||
dev->compositionComplete = &compositionComplete;
|
||||
|
||||
int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);
|
||||
const_cast<uint32_t &>(dev->flags) = 0;
|
||||
const_cast<uint32_t &>(dev->width) = m->info.xres;
|
||||
const_cast<uint32_t &>(dev->height) = m->info.yres;
|
||||
const_cast<int &>(dev->stride) = stride;
|
||||
#ifdef GRALLOC_16_BITS
|
||||
const_cast<int &>(dev->format) = HAL_PIXEL_FORMAT_RGB_565;
|
||||
#else
|
||||
const_cast<int &>(dev->format) = HAL_PIXEL_FORMAT_BGRA_8888;
|
||||
#endif
|
||||
const_cast<float &>(dev->xdpi) = m->xdpi;
|
||||
const_cast<float &>(dev->ydpi) = m->ydpi;
|
||||
const_cast<float &>(dev->fps) = m->fps;
|
||||
const_cast<int &>(dev->minSwapInterval) = 0;
|
||||
const_cast<int &>(dev->maxSwapInterval) = 1;
|
||||
*device = &dev->common;
|
||||
|
||||
gralloc_vsync_enable(dev);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (C) 2010 ARM Limited. All rights reserved.
|
||||
*
|
||||
* Copyright (C) 2008 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.
|
||||
*/
|
||||
|
||||
#include <hardware/hardware.h>
|
||||
#include "gralloc_priv.h"
|
||||
|
||||
// Create a framebuffer device
|
||||
int framebuffer_device_open(hw_module_t const *module, const char *name, hw_device_t **device);
|
||||
|
||||
// Initialize the framebuffer (must keep module lock before calling
|
||||
int init_frame_buffer_locked(struct private_module_t *module);
|
||||
|
||||
// Allocate framebuffer buffer
|
||||
int fb_alloc_framebuffer(mali_gralloc_module *m, uint64_t consumer_usage, uint64_t producer_usage,
|
||||
buffer_handle_t *pHandle, int *stride, int *byte_stride);
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* Copyright (C) 2008 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.
|
||||
*/
|
||||
|
||||
#include <cutils/ashmem.h>
|
||||
#include <log/log.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#if GRALLOC_USE_GRALLOC1_API == 1
|
||||
#include <hardware/gralloc1.h>
|
||||
#else
|
||||
#include <hardware/gralloc.h>
|
||||
#endif
|
||||
|
||||
#include "mali_gralloc_module.h"
|
||||
#include "mali_gralloc_private_interface_types.h"
|
||||
#include "mali_gralloc_buffer.h"
|
||||
#include "gralloc_buffer_priv.h"
|
||||
|
||||
/*
|
||||
* Allocate shared memory for attribute storage. Only to be
|
||||
* used by gralloc internally.
|
||||
*
|
||||
* Return 0 on success.
|
||||
*/
|
||||
int gralloc_buffer_attr_allocate(private_handle_t *hnd)
|
||||
{
|
||||
int rval = -1;
|
||||
|
||||
if (!hnd)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hnd->share_attr_fd >= 0)
|
||||
{
|
||||
ALOGW("Warning share attribute fd already exists during create. Closing.");
|
||||
close(hnd->share_attr_fd);
|
||||
}
|
||||
|
||||
hnd->share_attr_fd = ashmem_create_region("gralloc_shared_attr", PAGE_SIZE);
|
||||
|
||||
if (hnd->share_attr_fd < 0)
|
||||
{
|
||||
ALOGE("Failed to allocate page for shared attribute region");
|
||||
goto err_ashmem;
|
||||
}
|
||||
|
||||
/*
|
||||
* Default protection on the shm region is PROT_EXEC | PROT_READ | PROT_WRITE.
|
||||
*
|
||||
* Personality flag READ_IMPLIES_EXEC which is used by some processes, namely gdbserver,
|
||||
* causes a mmap with PROT_READ to be translated to PROT_READ | PROT_EXEC.
|
||||
*
|
||||
* If we were to drop PROT_EXEC here with a call to ashmem_set_prot_region()
|
||||
* this can potentially cause clients to fail importing this gralloc attribute buffer
|
||||
* with EPERM error since PROT_EXEC is not allowed.
|
||||
*
|
||||
* Because of this we keep the PROT_EXEC flag.
|
||||
*/
|
||||
|
||||
hnd->attr_base = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, hnd->share_attr_fd, 0);
|
||||
|
||||
if (hnd->attr_base != MAP_FAILED)
|
||||
{
|
||||
/* The attribute region contains signed integers only.
|
||||
* The reason for this is because we can set a value less than 0 for
|
||||
* not-initialized values.
|
||||
*/
|
||||
attr_region *region = (attr_region *)hnd->attr_base;
|
||||
|
||||
memset(hnd->attr_base, 0xff, PAGE_SIZE);
|
||||
munmap(hnd->attr_base, PAGE_SIZE);
|
||||
hnd->attr_base = MAP_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
ALOGE("Failed to mmap shared attribute region");
|
||||
goto err_ashmem;
|
||||
}
|
||||
|
||||
rval = 0;
|
||||
goto out;
|
||||
|
||||
err_ashmem:
|
||||
|
||||
if (hnd->share_attr_fd >= 0)
|
||||
{
|
||||
close(hnd->share_attr_fd);
|
||||
hnd->share_attr_fd = -1;
|
||||
}
|
||||
|
||||
out:
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees the shared memory allocated for attribute storage.
|
||||
* Only to be used by gralloc internally.
|
||||
|
||||
* Return 0 on success.
|
||||
*/
|
||||
int gralloc_buffer_attr_free(private_handle_t *hnd)
|
||||
{
|
||||
int rval = -1;
|
||||
|
||||
if (!hnd)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hnd->share_attr_fd < 0)
|
||||
{
|
||||
ALOGE("Shared attribute region not avail to free");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hnd->attr_base != MAP_FAILED)
|
||||
{
|
||||
ALOGW("Warning shared attribute region mapped at free. Unmapping");
|
||||
munmap(hnd->attr_base, PAGE_SIZE);
|
||||
hnd->attr_base = MAP_FAILED;
|
||||
}
|
||||
|
||||
close(hnd->share_attr_fd);
|
||||
hnd->share_attr_fd = -1;
|
||||
rval = 0;
|
||||
|
||||
out:
|
||||
return rval;
|
||||
}
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* Copyright (C) 2014-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* Copyright (C) 2008 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 GRALLOC_BUFFER_PRIV_H_
|
||||
#define GRALLOC_BUFFER_PRIV_H_
|
||||
|
||||
#include "gralloc_priv.h"
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include "mali_gralloc_private_interface_types.h"
|
||||
|
||||
// private gralloc buffer manipulation API
|
||||
|
||||
struct attr_region
|
||||
{
|
||||
/* Rectangle to be cropped from the full frame (Origin in top-left corner!) */
|
||||
int crop_top;
|
||||
int crop_left;
|
||||
int crop_height;
|
||||
int crop_width;
|
||||
int use_yuv_transform;
|
||||
int use_sparse_alloc;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct attr_region attr_region;
|
||||
|
||||
/*
|
||||
* Allocate shared memory for attribute storage. Only to be
|
||||
* used by gralloc internally.
|
||||
*
|
||||
* Return 0 on success.
|
||||
*/
|
||||
int gralloc_buffer_attr_allocate(struct private_handle_t *hnd);
|
||||
|
||||
/*
|
||||
* Frees the shared memory allocated for attribute storage.
|
||||
* Only to be used by gralloc internally.
|
||||
|
||||
* Return 0 on success.
|
||||
*/
|
||||
int gralloc_buffer_attr_free(struct private_handle_t *hnd);
|
||||
|
||||
/*
|
||||
* Map the attribute storage area before attempting to
|
||||
* read/write from it.
|
||||
*
|
||||
* Return 0 on success.
|
||||
*/
|
||||
static inline int gralloc_buffer_attr_map(struct private_handle_t *hnd, int readwrite)
|
||||
{
|
||||
int rval = -1;
|
||||
int prot_flags = PROT_READ;
|
||||
|
||||
if (!hnd)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hnd->share_attr_fd < 0)
|
||||
{
|
||||
ALOGE("Shared attribute region not available to be mapped");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (readwrite)
|
||||
{
|
||||
prot_flags |= PROT_WRITE;
|
||||
}
|
||||
|
||||
hnd->attr_base = mmap(NULL, PAGE_SIZE, prot_flags, MAP_SHARED, hnd->share_attr_fd, 0);
|
||||
|
||||
if (hnd->attr_base == MAP_FAILED)
|
||||
{
|
||||
ALOGE("Failed to mmap shared attribute region err=%s", strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
rval = 0;
|
||||
|
||||
out:
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unmap the attribute storage area when done with it.
|
||||
*
|
||||
* Return 0 on success.
|
||||
*/
|
||||
static inline int gralloc_buffer_attr_unmap(struct private_handle_t *hnd)
|
||||
{
|
||||
int rval = -1;
|
||||
|
||||
if (!hnd)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hnd->attr_base != MAP_FAILED)
|
||||
{
|
||||
if (munmap(hnd->attr_base, PAGE_SIZE) == 0)
|
||||
{
|
||||
hnd->attr_base = MAP_FAILED;
|
||||
rval = 0;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read or write an attribute from/to the storage area.
|
||||
*
|
||||
* Return 0 on success.
|
||||
*/
|
||||
static inline int gralloc_buffer_attr_write(struct private_handle_t *hnd, buf_attr attr, int *val)
|
||||
{
|
||||
int rval = -1;
|
||||
|
||||
if (!hnd || !val || attr >= GRALLOC_ARM_BUFFER_ATTR_LAST)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hnd->attr_base != MAP_FAILED)
|
||||
{
|
||||
attr_region *region = (attr_region *)hnd->attr_base;
|
||||
|
||||
switch (attr)
|
||||
{
|
||||
case GRALLOC_ARM_BUFFER_ATTR_CROP_RECT:
|
||||
memcpy(®ion->crop_top, val, sizeof(int) * 4);
|
||||
rval = 0;
|
||||
break;
|
||||
|
||||
case GRALLOC_ARM_BUFFER_ATTR_AFBC_YUV_TRANS:
|
||||
region->use_yuv_transform = *val;
|
||||
rval = 0;
|
||||
break;
|
||||
|
||||
case GRALLOC_ARM_BUFFER_ATTR_AFBC_SPARSE_ALLOC:
|
||||
region->use_sparse_alloc = *val;
|
||||
rval = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return rval;
|
||||
}
|
||||
|
||||
static inline int gralloc_buffer_attr_read(struct private_handle_t *hnd, buf_attr attr, int *val)
|
||||
{
|
||||
int rval = -1;
|
||||
|
||||
if (!hnd || !val || attr >= GRALLOC_ARM_BUFFER_ATTR_LAST)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hnd->attr_base != MAP_FAILED)
|
||||
{
|
||||
attr_region *region = (attr_region *)hnd->attr_base;
|
||||
|
||||
switch (attr)
|
||||
{
|
||||
case GRALLOC_ARM_BUFFER_ATTR_CROP_RECT:
|
||||
memcpy(val, ®ion->crop_top, sizeof(int) * 4);
|
||||
rval = 0;
|
||||
break;
|
||||
|
||||
case GRALLOC_ARM_BUFFER_ATTR_AFBC_YUV_TRANS:
|
||||
*val = region->use_yuv_transform;
|
||||
rval = 0;
|
||||
break;
|
||||
|
||||
case GRALLOC_ARM_BUFFER_ATTR_AFBC_SPARSE_ALLOC:
|
||||
*val = region->use_sparse_alloc;
|
||||
rval = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return rval;
|
||||
}
|
||||
|
||||
#endif /* GRALLOC_BUFFER_PRIV_H_ */
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (C) 2010-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* Copyright (C) 2008 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 GRALLOC_HELPER_H_
|
||||
#define GRALLOC_HELPER_H_
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <android/log.h>
|
||||
|
||||
#ifndef AWAR
|
||||
#define AWAR(fmt, args...) \
|
||||
__android_log_print(ANDROID_LOG_WARN, "[Gralloc-Warning]", "%s:%d " fmt, __func__, __LINE__, ##args)
|
||||
#endif
|
||||
#ifndef AINF
|
||||
#define AINF(fmt, args...) __android_log_print(ANDROID_LOG_INFO, "[Gralloc]", fmt, ##args)
|
||||
#endif
|
||||
#ifndef AERR
|
||||
#define AERR(fmt, args...) \
|
||||
__android_log_print(ANDROID_LOG_ERROR, "[Gralloc-ERROR]", "%s:%d " fmt, __func__, __LINE__, ##args)
|
||||
#endif
|
||||
#ifndef AERR_IF
|
||||
#define AERR_IF(eq, fmt, args...) \
|
||||
if ((eq)) \
|
||||
AERR(fmt, args)
|
||||
#endif
|
||||
|
||||
#define GRALLOC_ALIGN(value, base) (((value) + ((base)-1)) & ~((base)-1))
|
||||
|
||||
#define GRALLOC_UNUSED(x) ((void)x)
|
||||
|
||||
static inline size_t round_up_to_page_size(size_t x)
|
||||
{
|
||||
return (x + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
|
||||
}
|
||||
|
||||
#endif /* GRALLOC_HELPER_H_ */
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (C) 2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* Copyright (C) 2008 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 GRALLOC_PRIV_H_
|
||||
#define GRALLOC_PRIV_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <linux/fb.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <cutils/native_handle.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#if GRALLOC_USE_GRALLOC1_API
|
||||
#include <hardware/gralloc1.h>
|
||||
#else
|
||||
#include <hardware/gralloc.h>
|
||||
#endif
|
||||
/**
|
||||
* mali_gralloc_formats.h needs the define for GRALLOC_MODULE_API_VERSION_0_3 and
|
||||
* GRALLOC_MODULE_API_VERSION_1_0, so include <gralloc1.h> or <gralloc.h> before
|
||||
* including mali_gralloc_formats.h
|
||||
**/
|
||||
#include "mali_gralloc_formats.h"
|
||||
#include "mali_gralloc_usages.h"
|
||||
#include "gralloc_helper.h"
|
||||
|
||||
#if defined(GRALLOC_MODULE_API_VERSION_0_3) || \
|
||||
(defined(GRALLOC_MODULE_API_VERSION_1_0) && !defined(GRALLOC_DISABLE_PRIVATE_BUFFER_DEF))
|
||||
|
||||
/*
|
||||
* This header file contains the private buffer definition. For gralloc 0.3 it will
|
||||
* always be exposed, but for gralloc 1.0 it will be removed at some point in the future.
|
||||
*
|
||||
* GRALLOC_DISABLE_PRIVATE_BUFFER_DEF is intended for DDKs to test while implementing
|
||||
* the new private API.
|
||||
*/
|
||||
#include "mali_gralloc_buffer.h"
|
||||
#endif
|
||||
|
||||
#if defined(GRALLOC_MODULE_API_VERSION_1_0)
|
||||
|
||||
/* gralloc 1.0 supports the new private interface that abstracts
|
||||
* the private buffer definition to a set of defined APIs.
|
||||
*/
|
||||
#include "mali_gralloc_private_interface.h"
|
||||
#endif
|
||||
|
||||
#endif /* GRALLOC_PRIV_H_ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue