Moved to 48khz sample rate
Change-Id: Ic163aa2158a878453eceb45e13623a2deff44740
diff --git a/system/dev/audio/gauss-tdm/gauss-tdm-stream.cpp b/system/dev/audio/gauss-tdm/gauss-tdm-stream.cpp
index 486c76e..9d37bcb 100644
--- a/system/dev/audio/gauss-tdm/gauss-tdm-stream.cpp
+++ b/system/dev/audio/gauss-tdm/gauss-tdm-stream.cpp
@@ -539,7 +539,7 @@
// enable mclk c, select fclk_div4 as source, divide by 20 to get 12.5MHz
// at 256 sclk/frame, this yields 48.828125kHz
// TODO(hollande) - switch to pll to get accurate timing for 48kHz
- regs_->mclk_ctl[MCLK_C] = (1 << 31) | (6 << 24) | (19);
+ regs_->mclk_ctl[MCLK_C] = (1 << 31) | (2 << 24) | (9);
// configure mst_sclk_gen
regs_->sclk_ctl[MCLK_C].ctl0 = (0x03 << 30) | (1 << 20) | (0 << 10) | 255;
diff --git a/system/dev/board/gauss/gauss.c b/system/dev/board/gauss/gauss.c
index e7c7b3c..fa5e3e0 100644
--- a/system/dev/board/gauss/gauss.c
+++ b/system/dev/board/gauss/gauss.c
@@ -147,6 +147,18 @@
goto fail;
}
+ status = a113_clk_init(&bus->clocks, bus->a113);
+ if (status != ZX_OK) {
+ zxlogf(ERROR, "a113_clk_init failed: %d\n",status);
+ goto fail;
+ }
+
+ printf("HHI_MPLL_CNTL9 = %08x\n",a113_clk_get_reg(bus->clocks,0xa8));
+ printf("HHI_MPLL_TOP_MISC = %08x\n",a113_clk_get_reg(bus->clocks,0xba));
+ a113_clk_set_mpll2(bus->clocks, 48000*256*20);
+ printf("HHI_MPLL_CNTL9 = %08x\n",a113_clk_get_reg(bus->clocks,0xa8));
+ printf("HHI_MPLL_TOP_MISC = %08x\n",a113_clk_get_reg(bus->clocks,0xba));
+
bus->usb_mode_switch.ops = &usb_mode_switch_ops;
bus->usb_mode_switch.ctx = bus;
diff --git a/system/dev/board/gauss/gauss.h b/system/dev/board/gauss/gauss.h
index fa591fa..1a6095a 100644
--- a/system/dev/board/gauss/gauss.h
+++ b/system/dev/board/gauss/gauss.h
@@ -8,12 +8,15 @@
#include <ddk/protocol/platform-bus.h>
#include <ddk/protocol/usb-mode-switch.h>
#include <soc/aml-a113/a113-bus.h>
+#include <soc/aml-a113/a113-clocks.h>
+
typedef struct {
platform_bus_protocol_t pbus;
a113_bus_t* a113;
usb_mode_switch_protocol_t usb_mode_switch;
io_buffer_t usb_phy;
+ a113_clk_dev_t *clocks;
} gauss_bus_t;
// gauss-audio.c
diff --git a/system/dev/soc/aml-a113/a113-clocks.c b/system/dev/soc/aml-a113/a113-clocks.c
new file mode 100644
index 0000000..566f195
--- /dev/null
+++ b/system/dev/soc/aml-a113/a113-clocks.c
@@ -0,0 +1,85 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdint.h>
+#include <threads.h>
+#include <unistd.h>
+
+
+#include <bits/limits.h>
+#include <ddk/debug.h>
+#include <hw/reg.h>
+
+#include <zircon/assert.h>
+#include <zircon/types.h>
+
+#include <soc/aml-a113/a113-clocks.h>
+
+
+#define SDM_FRACTIONALITY 16384
+#define A113_FIXED_PLL_RATE 2000000000
+
+#define DIV_ROUND_UP(n,d) ((n + d - 1) / d)
+/* create instance of a113_clock_t and do basic initialization.
+*/
+zx_status_t a113_clk_init(a113_clk_dev_t **device, a113_bus_t *host_bus) {
+
+ *device = calloc(1, sizeof(a113_clk_dev_t));
+ if (!(*device)) {
+ return ZX_ERR_NO_MEMORY;
+ }
+
+ (*device)->host_bus = host_bus; // TODO - might not need this
+
+ zx_handle_t resource = get_root_resource();
+ zx_status_t status;
+
+ status = io_buffer_init_physical(&(*device)->regs_iobuff, A113_CLOCKS_BASE_PHYS,
+ PAGE_SIZE, resource, ZX_CACHE_POLICY_UNCACHED_DEVICE);
+
+ if (status != ZX_OK) {
+ zxlogf(ERROR, "a113_clk_init: io_buffer_init_physical failed %d\n", status);
+ goto init_fail;
+ }
+
+ (*device)->virt_regs = (zx_vaddr_t)(io_buffer_virt(&(*device)->regs_iobuff));
+
+ return ZX_OK;
+
+init_fail:
+ if (*device) {
+ io_buffer_release(&(*device)->regs_iobuff);
+ free(*device);
+ };
+ return status;
+}
+
+static void a113_clk_update_reg(a113_clk_dev_t *dev, uint32_t offset,
+ uint32_t pos,
+ uint32_t bits,
+ uint32_t value) {
+ uint32_t reg = a113_clk_get_reg(dev,offset);
+ reg &= ~(((1 << bits) - 1) << pos);
+ reg |= (value & ((1 << bits) - 1)) << pos;
+ a113_clk_set_reg(dev,offset,reg);
+}
+
+zx_status_t a113_clk_set_mpll2(a113_clk_dev_t *device, uint64_t rate) {
+
+ uint64_t n = A113_FIXED_PLL_RATE/rate; //calculate the integer ratio;
+ printf("Integer divider = %ld\n",n);
+
+ uint64_t sdm = DIV_ROUND_UP((A113_FIXED_PLL_RATE - n * rate) * SDM_FRACTIONALITY, rate);
+ printf("Fractional divider = %ld\n",sdm);
+
+ a113_clk_update_reg(device, 0xa8, 0, 14, (uint32_t)sdm);
+ a113_clk_update_reg(device, 0xa8, 16, 9, (uint32_t)n);
+ a113_clk_update_reg(device, 0xa8, 15, 1, 1);
+ a113_clk_update_reg(device, 0xa8, 14, 1, 1);
+
+ a113_clk_update_reg(device, 0xba, 2, 1, 1);
+
+
+ return ZX_OK;
+}
diff --git a/system/dev/soc/aml-a113/include/soc/aml-a113/a113-clocks.h b/system/dev/soc/aml-a113/include/soc/aml-a113/a113-clocks.h
new file mode 100644
index 0000000..b352ca4
--- /dev/null
+++ b/system/dev/soc/aml-a113/include/soc/aml-a113/a113-clocks.h
@@ -0,0 +1,31 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#pragma once
+
+#include <ddk/io-buffer.h>
+#include <ddk/protocol/platform-bus.h>
+
+#include "a113-bus.h"
+
+#define A113_CLOCKS_BASE_PHYS 0xff63c000
+
+typedef struct {
+ a113_bus_t *host_bus;
+ io_buffer_t regs_iobuff;
+ zx_vaddr_t virt_regs;
+} a113_clk_dev_t;
+
+
+static inline uint32_t a113_clk_get_reg(a113_clk_dev_t *dev, uint32_t offset) {
+ return ((uint32_t *)dev->virt_regs)[offset];
+}
+
+static inline uint32_t a113_clk_set_reg(a113_clk_dev_t *dev, uint32_t offset, uint32_t value) {
+ ((uint32_t *)dev->virt_regs)[offset] = value;
+ return ((uint32_t *)dev->virt_regs)[offset];
+}
+
+zx_status_t a113_clk_init(a113_clk_dev_t **device, a113_bus_t *host_bus);
+zx_status_t a113_clk_set_mpll2(a113_clk_dev_t *device, uint64_t rate);
diff --git a/system/dev/soc/aml-a113/rules.mk b/system/dev/soc/aml-a113/rules.mk
index 564a45b..4bde6d4 100644
--- a/system/dev/soc/aml-a113/rules.mk
+++ b/system/dev/soc/aml-a113/rules.mk
@@ -9,6 +9,7 @@
MODULE_TYPE := userlib
MODULE_SRCS += \
+ $(LOCAL_DIR)/a113-clocks.c \
$(LOCAL_DIR)/a113-gpio.c \
$(LOCAL_DIR)/a113-i2c.c \
$(LOCAL_DIR)/aml-i2c.c \