diff --git a/system/dev/board/sherlock/sherlock-camera.cpp b/system/dev/board/sherlock/sherlock-camera.cpp index 0fb1639f7d65236a95b787b1522bf2690d69e33c..7fbdc8c7252753b3072ee5bec9d5924aefa0ae08 100644 --- a/system/dev/board/sherlock/sherlock-camera.cpp +++ b/system/dev/board/sherlock/sherlock-camera.cpp @@ -50,21 +50,6 @@ constexpr pbus_mmio_t mipi_mmios[] = { .base = T931_HIU_BASE, .length = T931_HIU_LENGTH, }, - // Power domain - { - .base = T931_POWER_DOMAIN_BASE, - .length = T931_POWER_DOMAIN_LENGTH, - }, - // Memory PD - { - .base = T931_MEMORY_PD_BASE, - .length = T931_MEMORY_PD_LENGTH, - }, - // Reset - { - .base = T931_RESET_BASE, - .length = T931_RESET_LENGTH, - }, }; constexpr camera_sensor_t isp_mipi[] = { @@ -119,6 +104,29 @@ constexpr pbus_i2c_channel_t sensor_i2c[] = { }, }; +constexpr pbus_mmio_t isp_mmios[] = { + // HIU for clocks. + { + .base = T931_HIU_BASE, + .length = T931_HIU_LENGTH, + }, + // Power domain + { + .base = T931_POWER_DOMAIN_BASE, + .length = T931_POWER_DOMAIN_LENGTH, + }, + // Memory PD + { + .base = T931_MEMORY_PD_BASE, + .length = T931_MEMORY_PD_LENGTH, + }, + // Reset + { + .base = T931_RESET_BASE, + .length = T931_RESET_LENGTH, + }, +}; + constexpr pbus_gpio_t sensor_gpios[] = { { // vana-enable @@ -177,6 +185,8 @@ static pbus_dev_t isp_dev = []() { dev.vid = PDEV_VID_ARM; dev.pid = PDEV_PID_ISP; dev.did = PDEV_DID_ARM_MALI_IV009; + dev.mmio_list = isp_mmios; + dev.mmio_count = countof(isp_mmios); dev.metadata_list = isp_metadata; dev.metadata_count = countof(isp_metadata); dev.child_list = &isp_children; diff --git a/system/dev/camera/aml-mipicsi/aml-mipi-regs.h b/system/dev/camera/aml-mipicsi/aml-mipi-regs.h index c6bb2a293be0532513cf37d91e3be2d875ad5e06..192beb0bc14e211a1eba0b15c52351730d9dd0f9 100644 --- a/system/dev/camera/aml-mipicsi/aml-mipi-regs.h +++ b/system/dev/camera/aml-mipicsi/aml-mipi-regs.h @@ -121,16 +121,4 @@ // CLK offsets. #define HHI_MIPI_ISP_CLK_CNTL (0x70 << 2) #define HHI_MIPI_CSI_PHY_CLK_CNTL (0xD0 << 2) -#define HHI_CSI_PHY_CNTL0 (0xD3 << 2) -#define HHI_CSI_PHY_CNTL1 (0x114 << 2) -// Power domain. -#define AO_RTI_GEN_PWR_SLEEP0 (0x3a << 2) -#define AO_RTI_GEN_PWR_ISO0 (0x3b << 2) - -// Memory PD. -#define HHI_ISP_MEM_PD_REG0 (0x45 << 2) -#define HHI_ISP_MEM_PD_REG1 (0x46 << 2) - -// Reset -#define RESET4_LEVEL 0x90 diff --git a/system/dev/camera/aml-mipicsi/aml-mipi.cpp b/system/dev/camera/aml-mipicsi/aml-mipi.cpp index de8e185cc2da969f26da801a72d50c9ce35e9174..f4e5da4a247f70729d935d45a3336026a6d5efeb 100644 --- a/system/dev/camera/aml-mipicsi/aml-mipi.cpp +++ b/system/dev/camera/aml-mipicsi/aml-mipi.cpp @@ -29,9 +29,6 @@ constexpr uint32_t kAphy0 = 1; constexpr uint32_t kCsiHost0 = 2; constexpr uint32_t kMipiAdap = 3; constexpr uint32_t kHiu = 4; -constexpr uint32_t kPowerDomain = 5; -constexpr uint32_t kMemoryDomain = 6; -constexpr uint32_t kReset = 7; // CLK Shifts & Masks constexpr uint32_t kClkMuxMask = 0xfff; @@ -39,31 +36,6 @@ constexpr uint32_t kClkEnableShift = 8; } // namespace -void AmlMipiDevice::IspHWReset(bool reset) { - if (reset) { - reset_mmio_->ClearBits32(1 << 1, RESET4_LEVEL); - } else { - reset_mmio_->SetBits32(1 << 1, RESET4_LEVEL); - } -} - -void AmlMipiDevice::PowerUpIsp() { - // set bit[18-19]=0 - power_mmio_->ClearBits32(1 << 18 | 1 << 19, AO_RTI_GEN_PWR_SLEEP0); - zx_nanosleep(zx_deadline_after(ZX_MSEC(5))); - - // set bit[18-19]=0 - power_mmio_->ClearBits32(1 << 18 | 1 << 19, AO_RTI_GEN_PWR_ISO0); - - // MEM_PD_REG0 set 0 - memory_pd_mmio_->Write32(0, HHI_ISP_MEM_PD_REG0); - // MEM_PD_REG1 set 0 - memory_pd_mmio_->Write32(0, HHI_ISP_MEM_PD_REG1); - - hiu_mmio_->Write32(0x5b446585, HHI_CSI_PHY_CNTL0); - hiu_mmio_->Write32(0x803f4321, HHI_CSI_PHY_CNTL1); -} - void AmlMipiDevice::InitMipiClock() { // clear existing values hiu_mmio_->ClearBits32(kClkMuxMask, HHI_MIPI_ISP_CLK_CNTL); @@ -117,24 +89,6 @@ zx_status_t AmlMipiDevice::InitPdev(zx_device_t* parent) { return status; } - status = pdev_.MapMmio(kPowerDomain, &power_mmio_); - if (status != ZX_OK) { - zxlogf(ERROR, "%s: pdev_.MapMmio failed %d\n", __func__, status); - return status; - } - - status = pdev_.MapMmio(kMemoryDomain, &memory_pd_mmio_); - if (status != ZX_OK) { - zxlogf(ERROR, "%s: pdev_.MapMmio failed %d\n", __func__, status); - return status; - } - - status = pdev_.MapMmio(kReset, &reset_mmio_); - if (status != ZX_OK) { - zxlogf(ERROR, "%s: pdev_.MapMmio failed %d\n", __func__, status); - return status; - } - // Get our bti. status = pdev_.GetBti(0, &bti_); if (status != ZX_OK) { @@ -226,18 +180,10 @@ void AmlMipiDevice::MipiCsi2Init(const mipi_info_t* info) { zx_status_t AmlMipiDevice::MipiCsiInit(const mipi_info_t* mipi_info, const mipi_adap_info_t* adap_info) { - // The ISP and MIPI module is in same power domain. - // So if we don't call the power sequence of ISP, the mipi module - // won't work and it will block accesses to the mipi register block. - PowerUpIsp(); - // Setup MIPI CSI PHY CLK to 200MHz. // Setup MIPI ISP CLK to 667MHz. InitMipiClock(); - IspHWReset(true); - IspHWReset(false); - // Initialize the PHY. MipiPhyInit(mipi_info); // Initialize the CSI Host. diff --git a/system/dev/camera/aml-mipicsi/aml-mipi.h b/system/dev/camera/aml-mipicsi/aml-mipi.h index 36e7fbfcd51e446d79423f3a0b7127f417f1edfb..cc1c9b04d4e93ae77cfaa30f6f4be2ff28ed42a7 100644 --- a/system/dev/camera/aml-mipicsi/aml-mipi.h +++ b/system/dev/camera/aml-mipicsi/aml-mipi.h @@ -83,10 +83,8 @@ private: void AdapReaderStart(const mipi_adap_info_t* info); void AdapFrontEndStart(const mipi_adap_info_t* info); - // MIPI & ISP Power and clock APIs. + // MIPI clock. void InitMipiClock(); - void PowerUpIsp(); - void IspHWReset(bool reset); // Debug. void DumpCsiPhyRegs(); @@ -103,9 +101,6 @@ private: std::optional<ddk::MmioBuffer> csi_host0_mmio_; std::optional<ddk::MmioBuffer> mipi_adap_mmio_; std::optional<ddk::MmioBuffer> hiu_mmio_; - std::optional<ddk::MmioBuffer> power_mmio_; - std::optional<ddk::MmioBuffer> memory_pd_mmio_; - std::optional<ddk::MmioBuffer> reset_mmio_; ddk::PDev pdev_; ddk::MipiCsiProtocolClient self_protocol_; diff --git a/system/dev/camera/arm-isp/arm-isp-regs.h b/system/dev/camera/arm-isp/arm-isp-regs.h new file mode 100644 index 0000000000000000000000000000000000000000..c894aaf4c9aeb24a1eeacc5f414f09d0aecf3be5 --- /dev/null +++ b/system/dev/camera/arm-isp/arm-isp-regs.h @@ -0,0 +1,18 @@ +// Copyright 2019 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. + +// Power domain. +#define AO_RTI_GEN_PWR_SLEEP0 (0x3a << 2) +#define AO_RTI_GEN_PWR_ISO0 (0x3b << 2) + +// Memory PD. +#define HHI_ISP_MEM_PD_REG0 (0x45 << 2) +#define HHI_ISP_MEM_PD_REG1 (0x46 << 2) + +// CLK offsets. +#define HHI_CSI_PHY_CNTL0 (0xD3 << 2) +#define HHI_CSI_PHY_CNTL1 (0x114 << 2) + +// Reset +#define RESET4_LEVEL 0x90 diff --git a/system/dev/camera/arm-isp/arm-isp.cpp b/system/dev/camera/arm-isp/arm-isp.cpp index bb332ed89a7db6c1931163fa5584b72e0f56ca0e..0c429e6fb62b0bbd4a9db01f9d223dcdb4a9ac1b 100644 --- a/system/dev/camera/arm-isp/arm-isp.cpp +++ b/system/dev/camera/arm-isp/arm-isp.cpp @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "arm-isp.h" +#include "arm-isp-regs.h" #include <ddk/binding.h> #include <ddk/debug.h> #include <ddk/metadata.h> @@ -18,6 +19,88 @@ namespace camera { +namespace { + +constexpr uint32_t kHiu = 0; +constexpr uint32_t kPowerDomain = 1; +constexpr uint32_t kMemoryDomain = 2; +constexpr uint32_t kReset = 3; + +} // namespace + +void ArmIspDevice::IspHWReset(bool reset) { + if (reset) { + reset_mmio_->ClearBits32(1 << 1, RESET4_LEVEL); + } else { + reset_mmio_->SetBits32(1 << 1, RESET4_LEVEL); + } +} + +void ArmIspDevice::PowerUpIsp() { + // set bit[18-19]=0 + power_mmio_->ClearBits32(1 << 18 | 1 << 19, AO_RTI_GEN_PWR_SLEEP0); + zx_nanosleep(zx_deadline_after(ZX_MSEC(5))); + + // set bit[18-19]=0 + power_mmio_->ClearBits32(1 << 18 | 1 << 19, AO_RTI_GEN_PWR_ISO0); + + // MEM_PD_REG0 set 0 + memory_pd_mmio_->Write32(0, HHI_ISP_MEM_PD_REG0); + // MEM_PD_REG1 set 0 + memory_pd_mmio_->Write32(0, HHI_ISP_MEM_PD_REG1); + + // Refer to reference source code + hiu_mmio_->Write32(0x5b446585, HHI_CSI_PHY_CNTL0); + hiu_mmio_->Write32(0x803f4321, HHI_CSI_PHY_CNTL1); +} + +zx_status_t ArmIspDevice::InitIsp() { + // The ISP and MIPI module is in same power domain. + // So if we don't call the power sequence of ISP, the mipi module + // won't work and it will block accesses to the mipi register block. + PowerUpIsp(); + + IspHWReset(true); + + // TODO(braval@): Interrupt Init() + + IspHWReset(false); + + return ZX_OK; +} + +zx_status_t ArmIspDevice::InitPdev(zx_device_t* parent) { + if (!pdev_.is_valid()) { + return ZX_ERR_NO_RESOURCES; + } + + zx_status_t status = pdev_.MapMmio(kHiu, &hiu_mmio_); + if (status != ZX_OK) { + zxlogf(ERROR, "%s: pdev_.MapMmio failed %d\n", __func__, status); + return status; + } + + status = pdev_.MapMmio(kPowerDomain, &power_mmio_); + if (status != ZX_OK) { + zxlogf(ERROR, "%s: pdev_.MapMmio failed %d\n", __func__, status); + return status; + } + + status = pdev_.MapMmio(kMemoryDomain, &memory_pd_mmio_); + if (status != ZX_OK) { + zxlogf(ERROR, "%s: pdev_.MapMmio failed %d\n", __func__, status); + return status; + } + + status = pdev_.MapMmio(kReset, &reset_mmio_); + if (status != ZX_OK) { + zxlogf(ERROR, "%s: pdev_.MapMmio failed %d\n", __func__, status); + return status; + } + + return status; +} + // static zx_status_t ArmIspDevice::Create(zx_device_t* parent) { fbl::AllocChecker ac; @@ -26,7 +109,12 @@ zx_status_t ArmIspDevice::Create(zx_device_t* parent) { return ZX_ERR_NO_MEMORY; } - zx_status_t status = isp_device->DdkAdd("arm-isp"); + zx_status_t status = isp_device->InitPdev(parent); + if (status != ZX_OK) { + return status; + } + + status = isp_device->DdkAdd("arm-isp"); if (status != ZX_OK) { zxlogf(ERROR, "arm-isp: Could not create arm-isp device: %d\n", status); return status; diff --git a/system/dev/camera/arm-isp/arm-isp.h b/system/dev/camera/arm-isp/arm-isp.h index 9e3f6be8e0a76b58f24138b4d11d39c6952d6f93..08090edbbb7750272c40fa344d879c6307a50b41 100644 --- a/system/dev/camera/arm-isp/arm-isp.h +++ b/system/dev/camera/arm-isp/arm-isp.h @@ -10,8 +10,8 @@ #include <ddk/protocol/platform/device.h> #include <ddktl/device.h> #include <ddktl/pdev.h> -#include <ddktl/protocol/ispimpl.h> #include <ddktl/protocol/isp.h> +#include <ddktl/protocol/ispimpl.h> #include <fbl/unique_ptr.h> #include <threads.h> @@ -30,7 +30,7 @@ public: DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(ArmIspDevice); explicit ArmIspDevice(zx_device_t* parent) - : IspDeviceType(parent) {} + : IspDeviceType(parent), pdev_(parent) {} ~ArmIspDevice(); @@ -41,10 +41,22 @@ public: void DdkUnbind(); // ZX_PROTOCOL_ISP ops. - void IspDummyCall() {}; + void IspDummyCall(){}; private: void ShutDown(); + zx_status_t InitPdev(zx_device_t* parent); + + void PowerUpIsp(); + void IspHWReset(bool reset); + zx_status_t InitIsp(); + + std::optional<ddk::MmioBuffer> power_mmio_; + std::optional<ddk::MmioBuffer> memory_pd_mmio_; + std::optional<ddk::MmioBuffer> hiu_mmio_; + std::optional<ddk::MmioBuffer> reset_mmio_; + + ddk::PDev pdev_; }; } // namespace camera