Drivers/IPU: add IPU driver for hikey970
Add IPU device driver and device tree source for HiKey970. Signed-off-by: zwx305167 <zwx305167@notesmail.huawei.com>
This commit is contained in:
Regular → Executable
+2
@@ -18,6 +18,8 @@
|
||||
#include "kirin970_ipc.dtsi"
|
||||
#include "kirin970-coresight.dtsi"
|
||||
#include "kirin970-drm.dtsi"
|
||||
#include "kirin970_ics_cs.dtsi"
|
||||
|
||||
/ {
|
||||
model = "HiKey970";
|
||||
compatible = "Hisilicon,kirin970-hikey970", "Hisilicon,kirin970";
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Hisilicon Ltd. Kirin970 SoC
|
||||
*
|
||||
* Copyright (C) 2014- Hisilicon Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* publishhed by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
/ {
|
||||
cambricon-ipu@ff400000{
|
||||
// vipu-supply = <&ics>;
|
||||
compatible = "hisilicon,cambricon-ipu";
|
||||
reg = <0x0 0xff400000 0x0 0x100000>,<0x0 0xff500000 0x0 0x100000>;
|
||||
interrupts = <0 293 4>;
|
||||
interrupt-names = "ipu_dma_irq";
|
||||
ics-platform = "kirin970_cs";
|
||||
// clocks = <&clk_gate_ics>;
|
||||
clocks = <&media2_crg KIRIN970_CLK_GATE_ICSFREQ>;
|
||||
clock-names = "clk-ics";
|
||||
status = "ok"
|
||||
ipu-and-vcodecbus-clock-rate {
|
||||
start-rate = <900000000>;
|
||||
stop-rate = <332000000>;
|
||||
ipu-low = <384000000>;
|
||||
ipu-middle = <600000000>;
|
||||
ipu-high = <900000000>;
|
||||
ipu-low-temperature = <600000000>;
|
||||
vcodecbus-low = <185000000>;
|
||||
vcodecbus-middle = <332000000>;
|
||||
vcodecbus-high = <450000000>;
|
||||
vcodecbus-default = <415000000>;
|
||||
vcodecbus-high2default = <225000000>;
|
||||
};
|
||||
iommu_info {
|
||||
start-addr = <0x40000>;
|
||||
iova-align = <0x1000>;
|
||||
size = <0x80000000>;
|
||||
};
|
||||
smmu_master {
|
||||
smmu-mstr-base-addr = <0xff4a0000>;
|
||||
smmu-mstr-glb-bypass = <0x0000>;
|
||||
smmu-mstr-end-ack = <0x001c>;
|
||||
smmu-mstr-smrx-start = <0x0028>;
|
||||
smmu-mstr-inpt-sel = <0x0034>;
|
||||
smmu-mstr-intmask = <0x0040>;
|
||||
smmu-mstr-intstat = <0x0048>;
|
||||
smmu-mstr-intclr = <0x004c>;
|
||||
smmu-mstr-dbg-port-in-0 = <0x0070>;
|
||||
smmu-mstr-dbg-port-out = <0x0078>;
|
||||
smmu-mstr-smrx-0-stream-0 = <0x0100>;
|
||||
smmu-mstr-smrx-0-stream-1 = <0x0104>;
|
||||
smmu-mstr-smrx-0-stream-2 = <0x0108>;
|
||||
smmu-mstr-smrx-0-stream-3 = <0x010c>;
|
||||
read-cmd-total-cnt-stream-0 = <0x0600>;
|
||||
read-cmd-total-cnt-stream-1 = <0x0604>;
|
||||
read-cmd-total-cnt-stream-2 = <0x0608>;
|
||||
read-cmd-miss-cnt-stream-0 = <0x0760>;
|
||||
read-cmd-miss-cnt-stream-1 = <0x0764>;
|
||||
read-cmd-miss-cnt-stream-2 = <0x0768>;
|
||||
read-data-total-cnt-stream-0 = <0x08c0>;
|
||||
read-data-total-cnt-stream-1 = <0x08c4>;
|
||||
read-data-total-cnt-stream-2 = <0x08c8>;
|
||||
read-cmd-case-cnt-stream-0 = <0x0a20>;
|
||||
read-cmd-case-cnt-stream-1 = <0x0a24>;
|
||||
read-cmd-case-cnt-stream-2 = <0x0a28>;
|
||||
read-cmd-case-cnt-stream-3 = <0x0a2c>;
|
||||
read-cmd-case-cnt-stream-4 = <0x0a30>;
|
||||
read-cmd-case-cnt-stream-5 = <0x0a34>;
|
||||
read-cmd-trans-latency = <0x0a38>;
|
||||
write-cmd-total-cnt = <0x0b00>;
|
||||
write-cmd-miss-cnt = <0x0c60>;
|
||||
write-data-total-cnt = <0x0dc0>;
|
||||
write-cmd-case-cnt-stream-0 = <0x0f20>;
|
||||
write-cmd-case-cnt-stream-1 = <0x0f24>;
|
||||
write-cmd-case-cnt-stream-2 = <0x0f28>;
|
||||
write-cmd-case-cnt-stream-3 = <0x0f2c>;
|
||||
write-cmd-case-cnt-stream-4 = <0x0f30>;
|
||||
write-cmd-case-cnt-stream-5 = <0x0f34>;
|
||||
write-cmd-trans-latency = <0x0f38>;
|
||||
};
|
||||
smmu_common {
|
||||
smmu-common-base-addr = <0xff480000>;
|
||||
smmu-scr = <0x0000>;
|
||||
smmu-intmask-ns = <0x0010>;
|
||||
smmu-intstat-ns = <0x0018>;
|
||||
smmu-intclr-ns = <0x001c>;
|
||||
smmu-cb-ttbr0 = <0x0204>;
|
||||
smmu-cb-ttbcr = <0x020c>;
|
||||
smmu-scachei-all = <0x0214>;
|
||||
smmu-fama-ctrl1-ns = <0x0224>;
|
||||
smmu-addr-msb = <0x0300>;
|
||||
smmu-err-rdaddr = <0x0304>;
|
||||
smmu-err-wraddr = <0x0308>;
|
||||
smmu-opref-addr = <0x03a4>;
|
||||
smmu-opref-ctrl = <0x03a8>;
|
||||
};
|
||||
ics_irq {
|
||||
ics-irq-base-addr = <0xff4a2000>;
|
||||
ics-irq-mask-ns = <0x0000>;
|
||||
ics-irq-status-ns = <0x0008>;
|
||||
ics-irq-clr-ns = <0x000c>;
|
||||
};
|
||||
ics_noc_bus {
|
||||
base-addr = <0xe8950000>;
|
||||
qos-type = <0x000c>;
|
||||
factor = <0x0010>;
|
||||
saturation = <0x0014>;
|
||||
qos_extcontrol = <0x0018>;
|
||||
};
|
||||
pmctrl {
|
||||
base-addr = <0xfff31000>;
|
||||
noc-power-idle-req = <0x0380>;
|
||||
noc-power-idle-ack = <0x0384>;
|
||||
noc-power-idle-stat = <0x0388>;
|
||||
};
|
||||
pctrl {
|
||||
base-addr = <0xe8a09000>;
|
||||
peri-stat3 = <0x00a0>;
|
||||
};
|
||||
media2 {
|
||||
base-addr = <0xe8900000>;
|
||||
peren0 = <0x000>;
|
||||
perdis0 = <0x004>;
|
||||
perclken0 = <0x008>;
|
||||
perstat0 = <0x00c>;
|
||||
perrsten0 = <0x030>;
|
||||
perrstdis0 = <0x034>;
|
||||
perrststat0 = <0x038>;
|
||||
};
|
||||
peri {
|
||||
base-addr = <0xfff35000>;
|
||||
clkdiv8 = <0xc8>;
|
||||
clkdiv18 = <0xf0>;
|
||||
perpwrstat = <0x158>;
|
||||
perpwrack = <0x15c>;
|
||||
peristat7 = <0x50c>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -260,6 +260,7 @@ CONFIG_VIRTIO_BLK=y
|
||||
CONFIG_SRAM=y
|
||||
CONFIG_UID_SYS_STATS=y
|
||||
CONFIG_HISI_HIKEY_USB=y
|
||||
CONFIG_HISI_ICS_IPU=y
|
||||
CONFIG_MEMORY_STATE_TIME=y
|
||||
CONFIG_TI_ST=y
|
||||
CONFIG_ST_HCI=y
|
||||
|
||||
@@ -561,6 +561,7 @@ static const struct hisi_divider_clock kirin970_media1_divider_clks[] = {
|
||||
static const struct hisi_gate_clock kirin970_media2_gate_sep_clks[] = {
|
||||
{ KIRIN970_CLK_GATE_VDECFREQ, "clk_gate_vdecfreq", "clk_div_vdec", CLK_SET_RATE_PARENT, 0x00, 8, 0, },
|
||||
{ KIRIN970_CLK_GATE_VENCFREQ, "clk_gate_vencfreq", "clk_div_venc", CLK_SET_RATE_PARENT, 0x00, 5, 0, },
|
||||
{ KIRIN970_CLK_GATE_ICSFREQ, "clk_gate_icsfreq", "clk_div_ics", CLK_SET_RATE_PARENT, 0x00, 2, 0, },
|
||||
};
|
||||
|
||||
static void kirin970_clk_crgctrl_init(struct device_node *np)
|
||||
|
||||
@@ -11,6 +11,7 @@ if HISILICON_PLATFORM
|
||||
source "drivers/hisi/mailbox/Kconfig"
|
||||
source "drivers/hisi/hifi_dsp/Kconfig"
|
||||
source "drivers/hisi/hifi_mailbox/Kconfig"
|
||||
source "drivers/hisi/ics/Kconfig"
|
||||
|
||||
endif #HISILICON_PLATFORM
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
obj-$(CONFIG_HISILICON_PLATFORM_MAILBOX) += mailbox/
|
||||
obj-$(CONFIG_HIFI_DSP_ONE_TRACK) += hifi_dsp/
|
||||
obj-$(CONFIG_HIFI_MAILBOX) += hifi_mailbox/
|
||||
|
||||
obj-$(CONFIG_HISI_ICS_IPU) += ics/
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# Cambricon IPU Platform Specific Drivers
|
||||
#
|
||||
|
||||
menuconfig HISI_ICS_IPU_PLATFORM
|
||||
bool "Platform supoort for Cambricon IPU Device"
|
||||
default y
|
||||
help
|
||||
Say Y here to get to see options for device drivers of various
|
||||
Cambricon IPU platforms. This option itself does not add any kernel code.
|
||||
|
||||
If you say N, all options in this submenu will be skipped and disabled.
|
||||
|
||||
if HISI_ICS_IPU_PLATFORM
|
||||
|
||||
config HISI_ICS_IPU
|
||||
tristate "Cambricon IPU Driver"
|
||||
default y
|
||||
help
|
||||
Cambricon IPU Platform driver.
|
||||
|
||||
config HISI_IPU_SET_VCODECBUS
|
||||
tristate "Allow IPU Driver to set VCODEC bus clock rate"
|
||||
default n
|
||||
help
|
||||
Allow IPU Driver to set VCODEC bus clock rate.
|
||||
|
||||
config HISI_IPU_MNTN
|
||||
tristate "Enable IPU Driver maintain function"
|
||||
default n
|
||||
help
|
||||
Enable IPU Driver maintain function.
|
||||
|
||||
config HISI_IPU_REGULATOR
|
||||
tristate "Enable IPU Driver regulator control"
|
||||
default n
|
||||
help
|
||||
Enable IPU Driver regulator control.
|
||||
|
||||
endif # HISI_ICS_IPU_PLATFORM
|
||||
@@ -0,0 +1,14 @@
|
||||
ifeq ($(es_low_freq),true)
|
||||
EXTRA_CFLAGS += -DCONFIG_ES_VDEC_LOW_FREQ
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_HISI_ICS_IPU) += cambricon_ipu.o
|
||||
obj-$(CONFIG_HISI_ICS_IPU) += ipu_smmu_drv.o
|
||||
obj-$(CONFIG_HISI_ICS_IPU) += ipu_clock.o
|
||||
obj-$(CONFIG_HISI_IPU_MNTN) += ipu_mntn.o
|
||||
ifneq ($(TARGET_BUILD_VARIANT),user)
|
||||
obj-$(CONFIG_HISI_ICS_IPU) += ics_debug_proxy.o
|
||||
obj-y += ics_debug.o
|
||||
endif
|
||||
|
||||
EXTRA_CFLAGS += -I$(srctree)/drivers/hisi/ap/platform/kirin970
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Generic driver head file for the cambricon ipu device.
|
||||
*
|
||||
* Copyright (C) 2016 Cambricon Limited
|
||||
*
|
||||
* Licensed under the GPL v2 or later.
|
||||
*/
|
||||
#ifndef _CAMBRICON_IPU_H
|
||||
#define _CAMBRICON_IPU_H
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/kthread.h>
|
||||
|
||||
#include "ipu_smmu_drv.h"
|
||||
#include "ipu_clock.h"
|
||||
|
||||
struct irq_reg_offset {
|
||||
unsigned int ics_irq_base_addr;
|
||||
unsigned int ics_irq_mask_ns;
|
||||
unsigned int ics_irq_clr_ns;
|
||||
};
|
||||
|
||||
struct ics_noc_bus_reg_offset {
|
||||
unsigned int base_addr;
|
||||
unsigned int qos_type;
|
||||
unsigned int factor;
|
||||
unsigned int saturation;
|
||||
unsigned int qos_extcontrol;
|
||||
};
|
||||
|
||||
struct pmctrl_reg_offset {
|
||||
unsigned int base_addr;
|
||||
unsigned int noc_power_idle_req;
|
||||
unsigned int noc_power_idle_ack;
|
||||
unsigned int noc_power_idle_stat;
|
||||
};
|
||||
|
||||
struct pctrl_reg_offset {
|
||||
unsigned int base_addr;
|
||||
unsigned int peri_stat3;
|
||||
};
|
||||
|
||||
struct media2_reg_offset {
|
||||
unsigned int base_addr;
|
||||
unsigned int peren0;
|
||||
unsigned int perdis0;
|
||||
unsigned int perclken0;
|
||||
unsigned int perstat0;
|
||||
unsigned int perrsten0;
|
||||
unsigned int perrstdis0;
|
||||
unsigned int perrststat0;
|
||||
};
|
||||
|
||||
struct peri_reg_offset {
|
||||
unsigned int base_addr;
|
||||
unsigned int clkdiv8;
|
||||
unsigned int clkdiv18;
|
||||
unsigned int perpwrstat;
|
||||
unsigned int perpwrack;
|
||||
unsigned int peristat7;
|
||||
};
|
||||
|
||||
enum ipu_reset_trategy {
|
||||
IPU_RESET_UNSUPPORT = 0,
|
||||
IPU_RESET_BY_CONFIG_NOC_BUS,
|
||||
IPU_SOFT_RESET,
|
||||
};
|
||||
|
||||
enum ipu_bandwidth_lmt_trategy {
|
||||
IPU_BANDWIDTH_LMT_UNSUPPORT = 0,
|
||||
IPU_BANDWIDTH_LMT_BY_QOS,
|
||||
IPU_BANDWIDTH_LMT_BY_RW_OSD,
|
||||
};
|
||||
|
||||
struct ics_feature_tree {
|
||||
bool finish_irq_expand_ns;
|
||||
bool finish_irq_expand_p;
|
||||
bool finish_irq_expand_s;
|
||||
bool finish_irq_to_hifi;
|
||||
bool finish_irq_to_ivp;
|
||||
bool finish_irq_to_isp;
|
||||
bool finish_irq_to_lpm3;
|
||||
bool finish_irq_to_iocmu;
|
||||
bool smmu_port_select;
|
||||
bool level1_irq;
|
||||
bool performance_monitor;
|
||||
bool wr_qword;
|
||||
bool soft_watchdog_enable;
|
||||
bool lpm3_set_vcodecbus;
|
||||
bool smmu_mstr_hardware_start;
|
||||
unsigned int ipu_reset_when_in_error;
|
||||
unsigned int ipu_bandwidth_lmt;
|
||||
};
|
||||
typedef int Priority;
|
||||
|
||||
/* the ipu task type */
|
||||
typedef enum taskType {
|
||||
IPU_TASK_ENUM_START = 0,
|
||||
IPU_NONE_TASK = IPU_TASK_ENUM_START,
|
||||
/*First*/
|
||||
IPU_COMPUTE_TASK,
|
||||
IPU_SYNC_TASK,
|
||||
//Add new to here!
|
||||
IPU_TASK_ENUM_END
|
||||
} taskType_t;
|
||||
|
||||
typedef enum taskFlag{
|
||||
IPU_TASK_FLAG_START = 0,
|
||||
IPU_TASK_FLAG_NONE = IPU_TASK_FLAG_START,
|
||||
/*First*/
|
||||
IPU_TASK_FLAG_SYNC_WAITING,
|
||||
IPU_TASK_FLAG_SYNC_DONE,
|
||||
//Add new to here!
|
||||
IPU_TASK_FLAG_END
|
||||
} taskFlag_t;
|
||||
|
||||
struct ipu_wtd {
|
||||
bool enable;
|
||||
int status;
|
||||
struct mutex timer_mutex;
|
||||
struct timer_list timer;
|
||||
struct task_struct *task;
|
||||
struct semaphore sem;
|
||||
};
|
||||
|
||||
/* the ipu task element */
|
||||
typedef struct taskStruct {
|
||||
taskType_t taskType;//define different cmd type
|
||||
taskFlag_t* ptaskFlag;//use to mark task status
|
||||
unsigned long offchipInstAddr;
|
||||
unsigned long taskId;
|
||||
Priority prior;
|
||||
} taskElement;
|
||||
|
||||
#define BOOT_INST_SIZE (64)
|
||||
#define BOOT_INST_NUMBER (4)
|
||||
|
||||
/* this struct stores the temp data of boot instrument for IPU initialization after power-up */
|
||||
struct boot_inst_set {
|
||||
/* mutex */
|
||||
struct mutex boot_mutex;
|
||||
|
||||
/* store the value from IOCTL WRITE when IPU is off */
|
||||
unsigned int ipu_access_ddr_addr;
|
||||
|
||||
/* boot-instrument data */
|
||||
unsigned char boot_inst[BOOT_INST_SIZE * BOOT_INST_NUMBER];
|
||||
|
||||
/* size of boot-inst data */
|
||||
unsigned int boot_inst_size;
|
||||
|
||||
/* bool flag to record whether access_ddr_addr is recorded */
|
||||
bool access_ddr_addr_is_config;
|
||||
|
||||
/* bool flag to record whether boot_inst is recorded */
|
||||
bool boot_inst_recorded_is_config;
|
||||
};
|
||||
|
||||
/* cambricon ipu private data */
|
||||
struct cambricon_ipu_private
|
||||
{
|
||||
const char *name;
|
||||
unsigned int irq;
|
||||
bool ipu_device_opened;
|
||||
bool ipu_power_up;
|
||||
struct mutex power_mutex;
|
||||
struct mutex open_mutex;
|
||||
struct mutex bandwidth_lmt_mutex;
|
||||
struct boot_inst_set boot_inst_set;
|
||||
|
||||
struct smmu_statistic stat;
|
||||
bool smmu_stat_en;
|
||||
struct mutex stat_mutex;
|
||||
|
||||
/* config reg addr */
|
||||
unsigned int config_reg_length;
|
||||
phys_addr_t config_reg_phys_addr;
|
||||
void __iomem *config_reg_virt_addr;
|
||||
|
||||
/* inst reg addr */
|
||||
unsigned int inst_ram_size;
|
||||
phys_addr_t inst_ram_phys_addr;
|
||||
void __iomem *inst_ram_virt_addr;
|
||||
|
||||
/* ioremap addr */
|
||||
void __iomem *ics_irq_io_addr;
|
||||
void __iomem *noc_bus_io_addr;
|
||||
void __iomem *pmctrl_io_addr;
|
||||
void __iomem *pctrl_io_addr;
|
||||
void __iomem *media2_io_addr;
|
||||
void __iomem *peri_io_addr;
|
||||
|
||||
struct semaphore config_reg_sem;
|
||||
struct semaphore inst_ram_sem;
|
||||
struct semaphore llseek_sem;
|
||||
struct semaphore task_fifo_sem;
|
||||
|
||||
/* char device */
|
||||
struct cdev cdev; /* ipu char device */
|
||||
|
||||
/* platform device resource */
|
||||
struct resource *inst_mem, *cfg_mem;
|
||||
struct regulator *vipu_ip;
|
||||
|
||||
/* clock */
|
||||
struct ics_clock clk;
|
||||
|
||||
struct mutex reset_mutex;
|
||||
unsigned long reset_va;
|
||||
unsigned long smmu_ttbr0;
|
||||
void *smmu_rw_err_phy_addr;
|
||||
|
||||
struct irq_reg_offset irq_reg_offset;
|
||||
struct ics_noc_bus_reg_offset ics_noc_bus_reg_offset;
|
||||
struct pmctrl_reg_offset pmctrl_reg_offset;
|
||||
struct pctrl_reg_offset pctrl_reg_offset;
|
||||
struct media2_reg_offset media2_reg_offset;
|
||||
struct peri_reg_offset peri_reg_offset;
|
||||
|
||||
struct ics_feature_tree feature_tree;
|
||||
|
||||
struct ipu_wtd reset_wtd;
|
||||
|
||||
unsigned long computed_task_cnt;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define IOREAD_RANGE(base, size) \
|
||||
do { \
|
||||
unsigned long i; \
|
||||
DEBUG("IOREAD_RANGE(%p, %u)", (void*)(base), (u32)(size)); \
|
||||
for (i = 0; i < (size); i += 4) { \
|
||||
unsigned long addr = (unsigned long)(base) + i; \
|
||||
u32 val = ioread32((void*)addr); \
|
||||
if (val != 0) { \
|
||||
DEBUG("*(u32*)(%s + %lx): %x", #base, i, val); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define READ_IPU_VERSION_REGISTER() \
|
||||
do { \
|
||||
u32 version = ioread32((void*)((unsigned long)adapter->config_reg_virt_addr + IPU_VERSION_REG)); \
|
||||
DEBUG("IPU_VERSION: %x", version); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,803 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
#include "ics_debug.h"
|
||||
|
||||
#define CLASS_NAME "ics_debug"
|
||||
#define UNMASK_LPM3 (0)
|
||||
#define UNMASK_IOMCU (1)
|
||||
#define UNMASK_ISP (2)
|
||||
#define UNMASK_IVP (3)
|
||||
#define UNMASK_HIFI (4)
|
||||
|
||||
#define PERI_OFFSET_PEREN0 (0x000)
|
||||
#define PERI_OFFSET_PERDIS0 (0x004)
|
||||
#define PERI_OFFSET_PEREN6 (0x410)
|
||||
#define PERI_OFFSET_PERDIS6 (0x414)
|
||||
#define PERI_OFFSET_PERRSTEN4 (0x090)
|
||||
#define PERI_OFFSET_PERRSTDIS4 (0x094)
|
||||
#define PERI_OFFSET_CLKDIV18 (0x0F0)
|
||||
#define PERI_OFFSET_PERPWREN (0x150)
|
||||
#define PERI_OFFSET_PERPWRDIS (0x154)
|
||||
#define PERI_OFFSET_ISOEN (0x144)
|
||||
#define PERI_OFFSET_ISODIS (0x148)
|
||||
#define PERI_OFFSET_CLKDIV5 (0x0bc)
|
||||
#define PERI_OFFSET_CLKDIV8 (0x0c8)
|
||||
#define PERI_OFFSET_CLKDIV15 (0x0e4)
|
||||
|
||||
#define PERI_ISOEN_ICS_ISO_EN (0x00000100)
|
||||
#define PERI_ISODIS_ICS_ISO_UN (0x00000100)
|
||||
#define PERI_CLKDIV8_SEL_ICS_PLL2 (0xf0004000)
|
||||
#define PERI_CLKDIV8_SEL_ICS_PLL0 (0xf0002000)
|
||||
#define PERI_PERPWREN_ICSPWREN_EN (0x00000100)
|
||||
#define PERI_PERPWRDIS_ICS_PWR_DIS (0x00000100)
|
||||
#define PERI_PERRSTDIS4_IP_RST_MEDIA2 (0x00000001)
|
||||
#define PERI_CLKDIV15_SEL_FREQ_DIV4_ICS (0x7e000600)
|
||||
#define PERI_PERRSTEN4_IP_RST_MEDIA_CRG (0x00000002)
|
||||
#define PERI_CLKDIV8_SEL_VCODECBUS_PLL2 (0x000f0004)
|
||||
#define PERI_CLKDIV8_SEL_VCODECBUS_PLL0 (0x000f0002)
|
||||
#define PERI_CLKDIV15_SEL_FREQ_DIV3_ICS (0x7e000400)
|
||||
#define PERI_CLKDIV15_SEL_FREQ_DIV2_ICS (0x7e000200)
|
||||
#define PERI_CLKDIV18_SC_GT_CLK_ICS__EN (0x40000000)
|
||||
#define PERI_PERRSTEN4_IP_RST_MEDIA2_EN (0x00000001)
|
||||
#define PERI_CLKDIV18_SC_GT_CLK_VCODEBUS_EN (0x01000000)
|
||||
#define PERI_CLKDIV5_SET_FREQ_DIV4_VCODECBUS (0x003f0003)
|
||||
#define PERI_CLKDIV5_SET_FREQ_DIV5_VCODECBUS (0x003f0004)
|
||||
#define PERI_CLKDIV5_SET_FREQ_DIV8_VCODECBUS (0x003f0007)
|
||||
#define PERI_PEREN0_GT_CLK_VCODECBUS2DDRC_EN (0x00000020)
|
||||
#define PERI_PERRSTDIS4_IP_RST_MEDIA2_CRG_EN (0x00000002)
|
||||
#define PERI_PERDIS0_GT_CLK_VCODECBUS2DDRC_UN (0x00000020)
|
||||
#define PERI_CLKDIV18_SC_GT_CLK_ICS_OPEN_AND_EN (0x40004000)
|
||||
#define PERI_CLKDIV18_SC_GT_CLK_VCODEBUS_OPEN_AND_EN (0x01000100)
|
||||
#define PERI_PEREN6_GT_CLK_CFGBUS_MEDIA_AND_MEDIA2_EN (0x00010200)
|
||||
#define PERI_PERDIS6_GT_CLK_CFGBUS_MEDIA_AND_MEDIA2_EN (0x00010200)
|
||||
|
||||
#define MEDIA2_OFFSET_PEREN0 (0x000)
|
||||
#define MEDIA2_OFFSET_PERDIS0 (0x004)
|
||||
#define MEDIA2_OFFSET_PERRSTEN0 (0x030)
|
||||
#define MEDIA2_OFFSET_PERRSTDIS0 (0x034)
|
||||
|
||||
#define MEDIA2_PEREN0_GT_CLK_VCODEBUS_EN (0x00000200)
|
||||
#define MEDIA2_PERDIS0_GT_CLK_VCODEBUS_UN (0x00000200)
|
||||
#define MEDIA2_PEREN0_GT_CLK_ICS_AND_NOC_ICS_AND_NOC_ICS_CFG_EN (0x00000007)
|
||||
#define MEDIA2_PERDIS0_GT_CLK_ICS_AND_NOC_ICS_AND_NOC_ICS_CFG_UN (0x00000007)
|
||||
#define MEDIA2_PERRSTEN0_IP_RST_ICS_AND_NOC_ICS_AND_NOC_ICS_CFG_EN (0x00000038)
|
||||
#define MEDIA2_PERRSTDIS0_IP_RST_ICS_AND_NOC_ICS_AND_NOC_ICS_CFG_UN (0x00000038)
|
||||
|
||||
#define PMCTRL_OFFSET_NOC_POWER_IDLEREQ_0 (0x380)
|
||||
#define PMCTRL_OFFSET_NOC_POWER_IDLEACK_0 (0x384)
|
||||
#define PMCTRL_OFFSET_NOC_POWER_IDLE_0 (0x388)
|
||||
|
||||
#define PMCTRL_NOC_POWER_IDLE_0_NOC_ICS_POWER_IDLE (0x200)
|
||||
#define PMCTRL_NOC_POWER_IDLE_0_NOC_ICS_POWER_IDLE_UN (0x0)
|
||||
#define PMCTRL_NOC_POWER_IDLE_0_NOC_ICS_POWER_IDLE_EN (0x200)
|
||||
#define PMCTRL_NOC_POWER_IDLEACK_0_NOC_ICS_POWER_IDLEACK (0x200)
|
||||
#define PMCTRL_NOC_POWER_IDLEACK_0_NOC_ICS_POWER_IDLEACK_UN (0x0)
|
||||
#define PMCTRL_NOC_POWER_IDLEACK_0_NOC_ICS_POWER_IDLEACK_EN (0x200)
|
||||
#define PMCTRL_NOC_POWER_IDLEACK_0_NOC_VCODEC_BUS_POWER_IDLEACK (0x10)
|
||||
#define PMCTRL_NOC_POWER_IDLE_0_NOC_VCODEC_BUS_POWER_IDLE_STATUS (0x10)
|
||||
#define PMCTRL_NOC_POWER_IDLEACK_0_NOC_VCODEC_BUS_POWER_IDLEACK_UN (0x0)
|
||||
#define PMCTRL_NOC_POWER_IDLEREQ_0_NOC_ICS_POWER_IDLEREQ_EN (0x02000000)
|
||||
#define PMCTRL_NOC_POWER_IDLEACK_0_NOC_VCODEC_BUS_POWER_IDLEACK_EN (0x10)
|
||||
#define PMCTRL_NOC_POWER_IDLE_0_NOC_VCODEC_BUS_POWER_IDLE_STATUS_UN (0x0)
|
||||
#define PMCTRL_NOC_POWER_IDLE_0_NOC_VCODEC_BUS_POWER_IDLE_STATUS_EN (0x10)
|
||||
#define PMCTRL_NOC_POWER_IDLEREQ_0_NOC_ICS_POWER_IDLEREQ_REQ_AND_EN (0x02000200)
|
||||
#define PMCTRL_NOC_NOC_POWER_IDLEREQ_0_NOC_VCODEC_BUS_POWER_IDLEREQ_EN (0x00100000)
|
||||
#define PMCTRL_NOC_NOC_POWER_IDLEREQ_0_NOC_VCODEC_BUS_POWER_IDLEREQ_REQ_AND_EN (0x00100010)
|
||||
|
||||
#define CONFIG_REG_VIRT_ADDR_OFFSET_ICS_VERSION (0x40)
|
||||
#define CONFIG_REG_VIRT_ADDR_OFFSET_ICS_BASE_ADDR (0x28)
|
||||
|
||||
#define ICS_IRQ_OFFSET_ICS_IRQ_MASK_LPMCU_FINISH (0x20)
|
||||
#define ICS_IRQ_OFFSET_ICS_IRQ_MASK_IOMCU_FINISH (0x30)
|
||||
#define ICS_IRQ_OFFSET_ICS_IRQ_MASK_ISPCPU_FINISH (0x40)
|
||||
#define ICS_IRQ_OFFSET_ICS_IRQ_MASK_IVP_FINISH (0x50)
|
||||
#define ICS_IRQ_OFFSET_ICS_IRQ_MASK_HIFI_FINISH (0x60)
|
||||
|
||||
static struct class *ics_class;
|
||||
|
||||
struct cambricon_ipu_private *ics_adapter;
|
||||
|
||||
static uint32_t setclkrate = 0;
|
||||
static uint32_t setprofile = 0;
|
||||
static uint32_t ipuopen = 0;
|
||||
static uint32_t ipurelease = 0;
|
||||
static uint32_t ipuversion = 0;
|
||||
static uint32_t resetproc = 0;
|
||||
static uint32_t ipurstcrtenv = 0;
|
||||
static uint32_t ipurstdstenv = 0;
|
||||
static uint32_t pusetreg = 0;
|
||||
static uint32_t pdsetreg = 0;
|
||||
static uint32_t rdcorereg = 0;
|
||||
static uint32_t wrcorereg = 0;
|
||||
static uint32_t wrregvbusclk = 0;
|
||||
static uint32_t wrregcnnclk = 0;
|
||||
static uint32_t wrreglmt = 0;
|
||||
|
||||
struct ics_test_iomap_addr {
|
||||
void __iomem *pmctrl_io_addr;
|
||||
void __iomem *pctrl_io_addr;
|
||||
void __iomem *sctrl_io_addr;
|
||||
void __iomem *media_io_addr;
|
||||
void __iomem *peri_io_addr;
|
||||
};
|
||||
struct ics_test_iomap_addr ics_test_iomap_addr;
|
||||
|
||||
unsigned long smmu_ttbr0_bk = 0;
|
||||
|
||||
static ssize_t setclkrate_show(struct class *class, struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = snprintf(buf, PAGE_SIZE, "setclkrate:0x%x!\n", setclkrate);
|
||||
ret += snprintf(buf+ret, (PAGE_SIZE-ret), "usage: echo clockRate>setclkrate\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t setclkrate_store(struct class *class, struct class_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (sscanf(buf, "%d", &setclkrate) != 1)
|
||||
return -EINVAL;
|
||||
printk(KERN_DEBUG"[%s]: setclkrate_store begin\n", __FUNCTION__);
|
||||
ics_adapter->clk.start_rate = setclkrate;
|
||||
if (ret) {
|
||||
printk(KERN_ERR"[%s]: call_ipu_clock_start failed\n", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
printk(KERN_DEBUG"[%s]: setclkrate_store end\n", __FUNCTION__);
|
||||
|
||||
return (ssize_t)size;
|
||||
}
|
||||
|
||||
static ssize_t setprofile_show(struct class *class, struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = snprintf(buf, PAGE_SIZE, "setprofile:0x%x!\n", setprofile);
|
||||
ret += snprintf(buf+ret, (PAGE_SIZE-ret), "usage: echo profile>setprofile\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t setprofile_store(struct class *class, struct class_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (sscanf(buf, "%d", &setprofile) != 1)
|
||||
return -EINVAL;
|
||||
printk(KERN_DEBUG"[%s]: setclkrate_store begin\n", __FUNCTION__);
|
||||
call_ipu_set_profile(setprofile);
|
||||
if (ret) {
|
||||
printk(KERN_ERR"[%s]: ipu_clock_set_profile failed\n", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
printk(KERN_DEBUG"[%s]: setprofile_store end\n", __FUNCTION__);
|
||||
|
||||
return (ssize_t)size;
|
||||
}
|
||||
|
||||
static ssize_t ipuopen_show(struct class *class, struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int ret =0;
|
||||
ret = snprintf(buf, PAGE_SIZE, "ipuopen:0x%x!\n", ipuopen);
|
||||
ret += snprintf(buf+ret, (PAGE_SIZE-ret), "usage: echo param>ipuopen\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t ipuopen_store(struct class *class, struct class_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
printk(KERN_DEBUG"[%s]: ipuopen_store begin\n", __FUNCTION__);
|
||||
|
||||
ret = call_regulator_ip_vipu_enable();
|
||||
if (ret) {
|
||||
printk(KERN_ERR"[%s]: call_regulator_ip_vipu_enable failed\n", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
printk(KERN_DEBUG"[%s]: call_regulator_ip_vipu_enable ok\n", __FUNCTION__);
|
||||
|
||||
call_ipu_clock_start(&ics_adapter->clk);
|
||||
if (ret) {
|
||||
printk(KERN_ERR"[%s]: IPU clock start failed\n", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
printk(KERN_DEBUG"[%s]: call_ipu_clock_start ok\n", __FUNCTION__);
|
||||
|
||||
call_ipu_smmu_init(ics_adapter->smmu_ttbr0,
|
||||
(unsigned long)ics_adapter->smmu_rw_err_phy_addr, ics_adapter->feature_tree.smmu_port_select, ics_adapter->feature_tree.smmu_mstr_hardware_start);
|
||||
printk(KERN_DEBUG"[%s]: call_ipu_smmu_init ok\n", __FUNCTION__);
|
||||
|
||||
call_ipu_interrupt_init();
|
||||
printk(KERN_DEBUG"[%s]: call_ipu_interrupt_init ok\n", __FUNCTION__);
|
||||
|
||||
printk(KERN_DEBUG"[%s]: ipuopen_store end\n", __FUNCTION__);
|
||||
|
||||
return (ssize_t)size;
|
||||
}
|
||||
|
||||
static ssize_t ipurelease_show(struct class *class, struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int ret =0;
|
||||
ret = snprintf(buf, PAGE_SIZE, "ipurelease:0x%x!\n", ipurelease);
|
||||
ret += snprintf(buf+ret, (PAGE_SIZE-ret), "usage: echo param>ipurelease\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t ipurelease_store(struct class *class, struct class_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
printk(KERN_DEBUG"[%s]: ipurelease_store begin\n", __FUNCTION__);
|
||||
|
||||
call_ipu_clock_set_rate(&ics_adapter->clk, ics_adapter->clk.stop_rate);
|
||||
printk(KERN_DEBUG"[%s]: call_ipu_clock_set_rate ok\n", __FUNCTION__);
|
||||
|
||||
call_ipu_clock_stop(&ics_adapter->clk);
|
||||
printk(KERN_DEBUG"[%s]: call_ipu_clock_stop ok\n", __FUNCTION__);
|
||||
|
||||
ret = call_regulator_ip_vipu_disable();
|
||||
if (ret) {
|
||||
printk(KERN_ERR"[%s]: No IPU device!\n", __FUNCTION__);
|
||||
return -EBUSY;
|
||||
}
|
||||
printk(KERN_DEBUG"[%s]: call_regulator_ip_vipu_disable ok\n", __FUNCTION__);
|
||||
ics_adapter->ipu_device_opened = 0;
|
||||
|
||||
printk(KERN_DEBUG"[%s]: ipurelease_store end\n", __FUNCTION__);
|
||||
return (ssize_t)size;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t ipuversion_show(struct class *class, struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int ret =0;
|
||||
unsigned int regval;
|
||||
|
||||
regval = ioread32((void *)((unsigned long)ics_adapter->config_reg_virt_addr + CONFIG_REG_VIRT_ADDR_OFFSET_ICS_VERSION));
|
||||
|
||||
ret = snprintf(buf, PAGE_SIZE, "ipuversion:0x%x, register value: 0x%x!\n", ipuversion, regval);
|
||||
DEBUG("read version %x, cached %d", regval, ipuversion);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t ipuversion_store(struct class *class, struct class_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int ret = 0, ver = 0;
|
||||
|
||||
if (sscanf(buf, "%x", &ver) != 1) {
|
||||
printk(KERN_ERR "[%s]: version error, invalid number format!\n", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ipuversion = ver;
|
||||
iowrite32(ver, (void *)((unsigned long)ics_adapter->config_reg_virt_addr + CONFIG_REG_VIRT_ADDR_OFFSET_ICS_VERSION));
|
||||
DEBUG("write version %x", ver);
|
||||
return (ssize_t)size;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t resetproc_show(struct class *class, struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int ret =0;
|
||||
ret = snprintf(buf, PAGE_SIZE, "resetproc:0x%x!\n", resetproc);
|
||||
ret += snprintf(buf+ret, (PAGE_SIZE-ret), "usage: echo param>resetproc\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t resetproc_store(struct class *class, struct class_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
printk(KERN_DEBUG"[%s]: begin\n", __FUNCTION__);
|
||||
call_ipu_reset_proc((unsigned int)ics_adapter->reset_va);
|
||||
printk(KERN_DEBUG"[%s]: end\n", __FUNCTION__);
|
||||
|
||||
return (ssize_t)size;
|
||||
}
|
||||
|
||||
static ssize_t ipurstcrtenv_show(struct class *class, struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int ret =0;
|
||||
ret = snprintf(buf, PAGE_SIZE, "ipu reset create environment:0x%x!\n", ipurstcrtenv);
|
||||
ret += snprintf(buf+ret, (PAGE_SIZE-ret), "usage: echo param>ipurstcrtenv (no need to pu ipu)\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t ipurstcrtenv_store(struct class *class, struct class_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
printk(KERN_DEBUG"[%s]: begin\n", __FUNCTION__);
|
||||
smmu_ttbr0_bk = ics_adapter->smmu_ttbr0;
|
||||
ics_adapter->smmu_ttbr0 = smmu_ttbr0_bk & 0xffffffff;
|
||||
printk(KERN_DEBUG"[%s]: end\n", __FUNCTION__);
|
||||
|
||||
return (ssize_t)size;
|
||||
}
|
||||
|
||||
static ssize_t ipurstdstenv_show(struct class *class, struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int ret =0;
|
||||
ret = snprintf(buf, PAGE_SIZE, "ipu reset destroy environment:0x%x!\n", ipurstdstenv);
|
||||
ret += snprintf(buf+ret, (PAGE_SIZE-ret), "usage: echo param>ipurstcrtenv (no need to pu ipu)\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t ipurstdstenv_store(struct class *class, struct class_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
printk(KERN_DEBUG"[%s]: begin\n", __FUNCTION__);
|
||||
ics_adapter->smmu_ttbr0 = smmu_ttbr0_bk;
|
||||
printk(KERN_DEBUG"[%s]: end\n", __FUNCTION__);
|
||||
|
||||
return (ssize_t)size;
|
||||
}
|
||||
|
||||
static ssize_t pusetreg_show(struct class *class, struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = snprintf(buf, PAGE_SIZE, "pusetreg:0x%x!\n", pusetreg);
|
||||
ret += snprintf(buf+ret, (PAGE_SIZE-ret), "usage: echo param>pusetreg\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t pusetreg_store(struct class *class, struct class_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
unsigned int read_value;
|
||||
|
||||
printk(KERN_DEBUG"[%s]: peri_io_addr:%p, media2_io_addr:%p, pmctrl_io_addr=%p\n", __FUNCTION__,
|
||||
ics_adapter->peri_io_addr, ics_adapter->media2_io_addr, ics_adapter->pmctrl_io_addr);
|
||||
|
||||
//set_pu_media2_subsys
|
||||
printk(KERN_DEBUG"[%s]:meidia module unrst\n",__FUNCTION__);
|
||||
iowrite32(PERI_PERRSTDIS4_IP_RST_MEDIA2_CRG_EN, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_PERRSTDIS4));
|
||||
|
||||
printk(KERN_DEBUG"[%s]:meidia module clk enable\n",__FUNCTION__);
|
||||
iowrite32(PERI_PEREN6_GT_CLK_CFGBUS_MEDIA_AND_MEDIA2_EN, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_PEREN6));
|
||||
udelay(1);
|
||||
|
||||
printk(KERN_DEBUG"[%s]:meidia module clk disable\n",__FUNCTION__);
|
||||
iowrite32(PERI_PERDIS6_GT_CLK_CFGBUS_MEDIA_AND_MEDIA2_EN, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_PERDIS6));
|
||||
udelay(1);
|
||||
printk(KERN_DEBUG"[%s]:meidia module unrst\n",__FUNCTION__);
|
||||
|
||||
iowrite32(PERI_PERRSTDIS4_IP_RST_MEDIA2, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_PERRSTDIS4));
|
||||
printk(KERN_DEBUG"[%s]:meidia module clk enable\n",__FUNCTION__);
|
||||
|
||||
iowrite32(PERI_PEREN6_GT_CLK_CFGBUS_MEDIA_AND_MEDIA2_EN, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_PEREN6));
|
||||
|
||||
//set_pu_vcodec
|
||||
printk(KERN_DEBUG"[%s]:vcodec module clk enable\n",__FUNCTION__);
|
||||
iowrite32(PERI_CLKDIV18_SC_GT_CLK_VCODEBUS_OPEN_AND_EN, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_CLKDIV18));
|
||||
iowrite32(MEDIA2_PEREN0_GT_CLK_VCODEBUS_EN, (void *)((unsigned long)ics_adapter->media2_io_addr + MEDIA2_OFFSET_PEREN0));
|
||||
iowrite32(PERI_PEREN0_GT_CLK_VCODECBUS2DDRC_EN, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_PEREN0));
|
||||
udelay(1);
|
||||
|
||||
printk(KERN_DEBUG"[%s]:vcodec module clk disable\n",__FUNCTION__);
|
||||
iowrite32(MEDIA2_PERDIS0_GT_CLK_VCODEBUS_UN, (void *)((unsigned long)ics_adapter->media2_io_addr + MEDIA2_OFFSET_PERDIS0));
|
||||
iowrite32(PERI_PERDIS0_GT_CLK_VCODECBUS2DDRC_UN, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_PERDIS0));
|
||||
udelay(1);
|
||||
|
||||
printk(KERN_DEBUG"[%s]:vcodec module clk enable\n",__FUNCTION__);
|
||||
iowrite32(MEDIA2_PEREN0_GT_CLK_VCODEBUS_EN, (void *)((unsigned long)ics_adapter->media2_io_addr + MEDIA2_OFFSET_PEREN0));
|
||||
iowrite32(PERI_PEREN0_GT_CLK_VCODECBUS2DDRC_EN, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_PEREN0));
|
||||
|
||||
printk(KERN_DEBUG"[%s]:vcodec bus idle clear\n",__FUNCTION__);
|
||||
iowrite32(PMCTRL_NOC_NOC_POWER_IDLEREQ_0_NOC_VCODEC_BUS_POWER_IDLEREQ_EN, (void *)((unsigned long)ics_adapter->pmctrl_io_addr+ PMCTRL_OFFSET_NOC_POWER_IDLEREQ_0));
|
||||
udelay(1);
|
||||
|
||||
read_value = ioread32((void *)((unsigned long)ics_adapter->pmctrl_io_addr+ PMCTRL_OFFSET_NOC_POWER_IDLEACK_0));
|
||||
if ((PMCTRL_NOC_POWER_IDLEACK_0_NOC_VCODEC_BUS_POWER_IDLEACK & PMCTRL_NOC_POWER_IDLEACK_0_NOC_VCODEC_BUS_POWER_IDLEACK_UN) != 0x0) {
|
||||
printk(KERN_ERR"[%s]: pu_codec:no expect power idleack value:%d!\n",
|
||||
__FUNCTION__ , read_value);
|
||||
return -EINVAL;
|
||||
}
|
||||
udelay(1);
|
||||
|
||||
read_value = ioread32((void *)((unsigned long)ics_adapter->pmctrl_io_addr + PMCTRL_OFFSET_NOC_POWER_IDLE_0));
|
||||
if ((read_value & PMCTRL_NOC_POWER_IDLE_0_NOC_VCODEC_BUS_POWER_IDLE_STATUS) != PMCTRL_NOC_POWER_IDLE_0_NOC_VCODEC_BUS_POWER_IDLE_STATUS_UN) {
|
||||
printk(KERN_ERR"[%s]: pu_codec:no expect power idle value:%d!\n",
|
||||
__FUNCTION__ , read_value);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
//set_pu_ics
|
||||
printk(KERN_DEBUG"[%s]:ipu module mtcmos on\n",__FUNCTION__);
|
||||
iowrite32(PERI_PERPWREN_ICSPWREN_EN, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_PERPWREN));
|
||||
udelay(100);
|
||||
|
||||
printk(KERN_DEBUG"[%s]:ipu module clk enable\n",__FUNCTION__);
|
||||
iowrite32(PERI_CLKDIV18_SC_GT_CLK_ICS_OPEN_AND_EN, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_CLKDIV18));
|
||||
iowrite32(MEDIA2_PEREN0_GT_CLK_ICS_AND_NOC_ICS_AND_NOC_ICS_CFG_EN, (void *)((unsigned long)ics_adapter->media2_io_addr + MEDIA2_OFFSET_PEREN0));
|
||||
udelay(1);
|
||||
|
||||
printk(KERN_DEBUG"[%s]:ipu module clk disable\n",__FUNCTION__);
|
||||
iowrite32(MEDIA2_PERDIS0_GT_CLK_ICS_AND_NOC_ICS_AND_NOC_ICS_CFG_UN, (void *)((unsigned long)ics_adapter->media2_io_addr + MEDIA2_OFFSET_PERDIS0));
|
||||
udelay(1);
|
||||
|
||||
printk(KERN_DEBUG"[%s]:ipu module iso disable\n",__FUNCTION__);
|
||||
iowrite32(PERI_ISODIS_ICS_ISO_UN, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_ISODIS));
|
||||
printk(KERN_DEBUG"[%s]:ipu module unrst\n",__FUNCTION__);
|
||||
iowrite32(MEDIA2_PERRSTDIS0_IP_RST_ICS_AND_NOC_ICS_AND_NOC_ICS_CFG_UN, (void *)((unsigned long)ics_adapter->media2_io_addr + MEDIA2_OFFSET_PERRSTDIS0));
|
||||
udelay(1);
|
||||
|
||||
printk(KERN_DEBUG"[%s]:ipu module clk enable\n",__FUNCTION__);
|
||||
iowrite32(MEDIA2_PEREN0_GT_CLK_ICS_AND_NOC_ICS_AND_NOC_ICS_CFG_EN, (void *)((unsigned long)ics_adapter->media2_io_addr + MEDIA2_OFFSET_PEREN0));
|
||||
printk(KERN_DEBUG"[%s]:ipu bus idle clear\n",__FUNCTION__);
|
||||
iowrite32(PMCTRL_NOC_POWER_IDLEREQ_0_NOC_ICS_POWER_IDLEREQ_EN, (void *)((unsigned long)ics_adapter->pmctrl_io_addr+ PMCTRL_OFFSET_NOC_POWER_IDLEREQ_0));
|
||||
udelay(1);
|
||||
|
||||
read_value = ioread32((void *)((unsigned long)ics_adapter->pmctrl_io_addr+ PMCTRL_OFFSET_NOC_POWER_IDLEACK_0));
|
||||
|
||||
if ((read_value & PMCTRL_NOC_POWER_IDLEACK_0_NOC_ICS_POWER_IDLEACK) != PMCTRL_NOC_POWER_IDLEACK_0_NOC_ICS_POWER_IDLEACK_UN) {
|
||||
printk(KERN_ERR"[%s]: pu_ics:no expect power idleack value:%d!\n",
|
||||
__FUNCTION__ , read_value);
|
||||
return -EINVAL;
|
||||
}
|
||||
udelay(1);
|
||||
|
||||
read_value = ioread32((void *)((unsigned long)ics_adapter->pmctrl_io_addr+ PMCTRL_OFFSET_NOC_POWER_IDLE_0));
|
||||
|
||||
if ((read_value & PMCTRL_NOC_POWER_IDLE_0_NOC_ICS_POWER_IDLE) != PMCTRL_NOC_POWER_IDLE_0_NOC_ICS_POWER_IDLE_UN) {
|
||||
printk(KERN_ERR"[%s]: pu_ics:no expect power idle value:%d!\n",
|
||||
__FUNCTION__ , read_value);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return (ssize_t)size;
|
||||
}
|
||||
|
||||
static ssize_t pdsetreg_show(struct class *class, struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = snprintf(buf, PAGE_SIZE, "pdsetreg:0x%x!\n", pdsetreg);
|
||||
ret += snprintf(buf+ret, (PAGE_SIZE-ret), "usage: echo param>pdsetreg\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t pdsetreg_store(struct class *class, struct class_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
unsigned int read_value;
|
||||
|
||||
//set_pd_ics
|
||||
printk(KERN_DEBUG"[%s]:ipu bus idle set\n",__FUNCTION__);
|
||||
iowrite32(PMCTRL_NOC_POWER_IDLEREQ_0_NOC_ICS_POWER_IDLEREQ_REQ_AND_EN, (void *)((unsigned long)ics_adapter->pmctrl_io_addr+ PMCTRL_OFFSET_NOC_POWER_IDLEREQ_0));
|
||||
udelay(1);
|
||||
|
||||
read_value = ioread32((void *)((unsigned long)ics_adapter->pmctrl_io_addr+ PMCTRL_OFFSET_NOC_POWER_IDLEACK_0));
|
||||
if((read_value & PMCTRL_NOC_POWER_IDLEACK_0_NOC_ICS_POWER_IDLEACK) != PMCTRL_NOC_POWER_IDLEACK_0_NOC_ICS_POWER_IDLEACK_EN) {
|
||||
printk(KERN_ERR"[%s]: pd_ics:no expect power idleack value:%d!\n",
|
||||
__FUNCTION__ , read_value);
|
||||
return -EINVAL;
|
||||
}
|
||||
udelay(1);
|
||||
|
||||
read_value = ioread32((void *)((unsigned long)ics_adapter->pmctrl_io_addr+ PMCTRL_OFFSET_NOC_POWER_IDLE_0));
|
||||
if((read_value & PMCTRL_NOC_POWER_IDLE_0_NOC_ICS_POWER_IDLE) != PMCTRL_NOC_POWER_IDLE_0_NOC_ICS_POWER_IDLE_EN) {
|
||||
printk(KERN_ERR"[%s]: pd_ics:no expect power idle value:%d!\n",
|
||||
__FUNCTION__ , read_value);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
printk(KERN_DEBUG"[%s]:ipu module clk disable\n",__FUNCTION__);
|
||||
iowrite32(MEDIA2_PERDIS0_GT_CLK_ICS_AND_NOC_ICS_AND_NOC_ICS_CFG_UN, (void *)((unsigned long)ics_adapter->media2_io_addr + MEDIA2_OFFSET_PERDIS0));
|
||||
udelay(1);
|
||||
|
||||
printk(KERN_DEBUG"[%s]:ipu module rst\n",__FUNCTION__);
|
||||
iowrite32(MEDIA2_PERRSTEN0_IP_RST_ICS_AND_NOC_ICS_AND_NOC_ICS_CFG_EN, (void *)((unsigned long)ics_adapter->media2_io_addr + MEDIA2_OFFSET_PERRSTEN0));
|
||||
udelay(1);
|
||||
|
||||
printk(KERN_DEBUG"[%s]:ipu module clk disable\n",__FUNCTION__);
|
||||
iowrite32(MEDIA2_PEREN0_GT_CLK_ICS_AND_NOC_ICS_AND_NOC_ICS_CFG_EN, (void *)((unsigned long)ics_adapter->media2_io_addr + MEDIA2_OFFSET_PEREN0));
|
||||
udelay(1);
|
||||
|
||||
printk(KERN_DEBUG"[%s]:ipu module clk disable\n",__FUNCTION__);
|
||||
iowrite32(MEDIA2_PERDIS0_GT_CLK_ICS_AND_NOC_ICS_AND_NOC_ICS_CFG_UN, (void *)((unsigned long)ics_adapter->media2_io_addr + MEDIA2_OFFSET_PERDIS0));
|
||||
iowrite32(PERI_CLKDIV18_SC_GT_CLK_ICS__EN, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_CLKDIV18));
|
||||
|
||||
printk(KERN_DEBUG"[%s]:ipu module iso\n",__FUNCTION__);
|
||||
iowrite32(PERI_ISOEN_ICS_ISO_EN, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_ISOEN));
|
||||
|
||||
printk(KERN_DEBUG"[%s]:ipu module mtcmos off\n",__FUNCTION__);
|
||||
iowrite32(PERI_PERPWRDIS_ICS_PWR_DIS, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_PERPWRDIS));
|
||||
|
||||
//set_pd_vcodec
|
||||
printk(KERN_DEBUG"[%s]:vcodec bus idle set\n",__FUNCTION__);
|
||||
iowrite32(PMCTRL_NOC_NOC_POWER_IDLEREQ_0_NOC_VCODEC_BUS_POWER_IDLEREQ_REQ_AND_EN, (void *)((unsigned long)ics_adapter->pmctrl_io_addr+ PMCTRL_OFFSET_NOC_POWER_IDLEREQ_0));
|
||||
udelay(1);
|
||||
|
||||
read_value = ioread32((void *)((unsigned long)ics_adapter->pmctrl_io_addr+ PMCTRL_OFFSET_NOC_POWER_IDLEACK_0));
|
||||
if((read_value & PMCTRL_NOC_POWER_IDLEACK_0_NOC_VCODEC_BUS_POWER_IDLEACK) != PMCTRL_NOC_POWER_IDLEACK_0_NOC_VCODEC_BUS_POWER_IDLEACK_EN) {
|
||||
printk(KERN_ERR"[%s]: pd_codec:no expect power idleack value:%d!\n",
|
||||
__FUNCTION__ , read_value);
|
||||
return -EINVAL;
|
||||
}
|
||||
udelay(1);
|
||||
|
||||
read_value = ioread32((void *)((unsigned long)ics_adapter->pmctrl_io_addr+ PMCTRL_OFFSET_NOC_POWER_IDLE_0));
|
||||
if((read_value & PMCTRL_NOC_POWER_IDLE_0_NOC_VCODEC_BUS_POWER_IDLE_STATUS) != PMCTRL_NOC_POWER_IDLE_0_NOC_VCODEC_BUS_POWER_IDLE_STATUS_EN) {
|
||||
printk(KERN_ERR"[%s]: pd_codec:no expect power idle value:%d!\n",
|
||||
__FUNCTION__ , read_value);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
printk(KERN_DEBUG"[%s]:vcodec module clk disable\n",__FUNCTION__);
|
||||
iowrite32(MEDIA2_PERDIS0_GT_CLK_VCODEBUS_UN, (void *)((unsigned long)ics_adapter->media2_io_addr + MEDIA2_OFFSET_PERDIS0));
|
||||
iowrite32(PERI_PERDIS0_GT_CLK_VCODECBUS2DDRC_UN, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_PERDIS0));
|
||||
iowrite32(PERI_CLKDIV18_SC_GT_CLK_VCODEBUS_EN, (void *)((unsigned long)ics_adapter->peri_io_addr+ PERI_OFFSET_CLKDIV18));
|
||||
|
||||
//set_pu_media2_subsys
|
||||
printk(KERN_DEBUG"[%s]:media module rst\n",__FUNCTION__);
|
||||
iowrite32(PERI_PERRSTEN4_IP_RST_MEDIA2_EN, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_PERRSTEN4));
|
||||
|
||||
printk(KERN_DEBUG"[%s]:media module clk disable\n",__FUNCTION__);
|
||||
iowrite32(PERI_PERDIS6_GT_CLK_CFGBUS_MEDIA_AND_MEDIA2_EN, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_PERDIS6));
|
||||
|
||||
printk(KERN_DEBUG"[%s]:media module unrst\n",__FUNCTION__);
|
||||
iowrite32(PERI_PERRSTEN4_IP_RST_MEDIA_CRG, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_PERRSTEN4));
|
||||
return (ssize_t)size;
|
||||
}
|
||||
|
||||
static ssize_t rdcorereg_show(struct class *class, struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = snprintf(buf, PAGE_SIZE, "rdcorereg:0x%x!\n", rdcorereg);
|
||||
ret += snprintf(buf+ret, (PAGE_SIZE-ret), "usage: echo param>rdcorereg\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t rdcorereg_store(struct class *class, struct class_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
unsigned int read_value;
|
||||
read_value = ioread32((void *)((unsigned long)ics_adapter->config_reg_virt_addr + CONFIG_REG_VIRT_ADDR_OFFSET_ICS_VERSION));
|
||||
|
||||
if (read_value != 0x44400a7c && read_value != 0x4440031b) {
|
||||
printk(KERN_ERR"[%s]: read_value error : 0x%x!\n", __FUNCTION__ , read_value);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return (ssize_t)size;
|
||||
}
|
||||
|
||||
static ssize_t wrcorereg_show(struct class *class, struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int ret =0;
|
||||
u32 value = 0;
|
||||
ret = snprintf(buf, PAGE_SIZE, "wrcorereg:0x%x!\n", wrcorereg);
|
||||
ret += snprintf(buf+ret, (PAGE_SIZE-ret), "usage: echo param>wrcorereg\n");
|
||||
value = ioread32((void *)((unsigned long)ics_adapter->config_reg_virt_addr + CONFIG_REG_VIRT_ADDR_OFFSET_ICS_BASE_ADDR));
|
||||
ret += snprintf(buf+ret, (PAGE_SIZE-ret), "register value: %u\n", value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t wrcorereg_store(struct class *class, struct class_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
unsigned int read_value;
|
||||
|
||||
if (sscanf(buf, "0x%x", &wrcorereg) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
iowrite32(wrcorereg, (void *)((unsigned long)ics_adapter->config_reg_virt_addr + CONFIG_REG_VIRT_ADDR_OFFSET_ICS_BASE_ADDR));
|
||||
udelay(1);
|
||||
|
||||
read_value = ioread32((void *)((unsigned long)ics_adapter->config_reg_virt_addr + CONFIG_REG_VIRT_ADDR_OFFSET_ICS_BASE_ADDR));
|
||||
|
||||
if (read_value != wrcorereg) {
|
||||
printk(KERN_ERR"[%s]: read_value error : 0x%x!\n", __FUNCTION__ , read_value);
|
||||
return -EINVAL;
|
||||
} else {
|
||||
printk(KERN_DEBUG "[%s]: write %lx success!\n", __FUNCTION__, (unsigned long)ics_adapter->config_reg_virt_addr + CONFIG_REG_VIRT_ADDR_OFFSET_ICS_BASE_ADDR);
|
||||
}
|
||||
|
||||
return (ssize_t)size;
|
||||
}
|
||||
|
||||
static ssize_t wrregvbusclk_show(struct class *class, struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = snprintf(buf, PAGE_SIZE, "wrregvbusclk:0x%x!\n", wrregvbusclk);
|
||||
ret += snprintf(buf+ret, (PAGE_SIZE-ret), "usage: echo param>wrregvbusclk\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t wrregvbusclk_store(struct class *class, struct class_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
if (sscanf(buf, "%d", &wrregvbusclk) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (wrregvbusclk != 480000000 && wrregvbusclk != 322000000 && wrregvbusclk != 207500000) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (wrregvbusclk == 480000000) {
|
||||
iowrite32(PERI_CLKDIV8_SEL_VCODECBUS_PLL2, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_CLKDIV8));
|
||||
iowrite32(PERI_CLKDIV5_SET_FREQ_DIV4_VCODECBUS, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_CLKDIV5));
|
||||
} else if(wrregvbusclk == 322000000){
|
||||
iowrite32(PERI_CLKDIV8_SEL_VCODECBUS_PLL0, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_CLKDIV8));
|
||||
iowrite32(PERI_CLKDIV5_SET_FREQ_DIV5_VCODECBUS, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_CLKDIV5));
|
||||
} else if(wrregvbusclk == 207500000){
|
||||
iowrite32(PERI_CLKDIV8_SEL_VCODECBUS_PLL0, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_CLKDIV8));
|
||||
iowrite32(PERI_CLKDIV5_SET_FREQ_DIV8_VCODECBUS, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_CLKDIV5));
|
||||
}
|
||||
|
||||
return (ssize_t)size;
|
||||
}
|
||||
|
||||
static ssize_t wrregcnnclk_show(struct class *class, struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = snprintf(buf, PAGE_SIZE, "wrregcnnclk:0x%x!\n", wrregcnnclk);
|
||||
ret += snprintf(buf+ret, (PAGE_SIZE-ret), "usage: echo param>wrregcnnclk\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t wrregcnnclk_store(struct class *class, struct class_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
if (sscanf(buf, "%d", &wrregcnnclk) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (wrregcnnclk != 960000000 && wrregvbusclk != 640000000 && wrregvbusclk != 415000000) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (wrregcnnclk == 960000000) {
|
||||
iowrite32(PERI_CLKDIV8_SEL_ICS_PLL2, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_CLKDIV8));
|
||||
iowrite32(PERI_CLKDIV15_SEL_FREQ_DIV2_ICS, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_CLKDIV15));
|
||||
} else if (wrregcnnclk == 640000000) {
|
||||
iowrite32(PERI_CLKDIV8_SEL_ICS_PLL2, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_CLKDIV8));
|
||||
iowrite32(PERI_CLKDIV15_SEL_FREQ_DIV3_ICS, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_CLKDIV15));
|
||||
} else if (wrregcnnclk == 415000000) {
|
||||
iowrite32(PERI_CLKDIV8_SEL_ICS_PLL0, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_CLKDIV8));
|
||||
iowrite32(PERI_CLKDIV15_SEL_FREQ_DIV4_ICS, (void *)((unsigned long)ics_adapter->peri_io_addr + PERI_OFFSET_CLKDIV15));
|
||||
}
|
||||
return (ssize_t)size;
|
||||
}
|
||||
|
||||
static ssize_t wrreglmt_show(struct class *class, struct class_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = snprintf(buf, PAGE_SIZE, "wrreglmt:0x%x!\n", wrreglmt);
|
||||
ret += snprintf(buf+ret, (PAGE_SIZE-ret), "usage: echo param>wrreglmt_es\n");
|
||||
ret += snprintf(buf+ret, (PAGE_SIZE-ret), "wrreglmt = 0xf6b ,ics core:400M,vcodec bus:207.5M\n");
|
||||
ret += snprintf(buf+ret, (PAGE_SIZE-ret), "wrreglmt = 0xaaa,ics core:640M,vcodec bus:480M\n");
|
||||
ret += snprintf(buf+ret, (PAGE_SIZE-ret), "wrreglmt = 0xdd5 ,ics core:830M,vcodec bus:480M\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t wrreglmt_store(struct class *class, struct class_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
void __iomem *axi;
|
||||
unsigned int read_value = 0;
|
||||
if (sscanf(buf, "0x%x", &wrreglmt) != 1)
|
||||
return -EINVAL;
|
||||
if (wrreglmt != 0xf6b &&
|
||||
wrreglmt != 0xaaa &&
|
||||
wrreglmt != 0xdd5 ) {
|
||||
printk(KERN_ERR"[%s]: limiter:input error value:%d!\n",
|
||||
__FUNCTION__ , wrreglmt);
|
||||
return -EINVAL;
|
||||
}
|
||||
axi = ioremap((unsigned long)0xe8950000,(unsigned long)0xfff);
|
||||
iowrite32(0x1,(void *)((unsigned long)axi+0x0c));
|
||||
udelay(10);
|
||||
iowrite32(wrreglmt,(void *)((unsigned long)axi+0x10));
|
||||
udelay(10);
|
||||
iowrite32(0x40, (void *)((unsigned long)axi+0x14));
|
||||
read_value = ioread32((void *)((unsigned long)axi+ 0x10));
|
||||
printk(KERN_DEBUG"[%s]:limit value = 0x%x",__FUNCTION__, read_value);
|
||||
iounmap(axi);
|
||||
return (ssize_t)size;
|
||||
}
|
||||
|
||||
static const struct class_attribute ics_attrs[] = {
|
||||
__ATTR(setclkrate, 0644, setclkrate_show, setclkrate_store),
|
||||
__ATTR(setprofile, 0644, setprofile_show, setprofile_store),
|
||||
__ATTR(ipuopen, 0644, ipuopen_show, ipuopen_store),
|
||||
__ATTR(ipurelease, 0644, ipurelease_show, ipurelease_store),
|
||||
__ATTR(ipuversion, 0644, ipuversion_show, ipuversion_store),
|
||||
__ATTR(resetproc, 0644, resetproc_show, resetproc_store),
|
||||
__ATTR(ipurstcrtenv, 0644, ipurstcrtenv_show, ipurstcrtenv_store),
|
||||
__ATTR(ipurstdstenv, 0644, ipurstdstenv_show, ipurstdstenv_store),
|
||||
__ATTR(pusetreg, 0644, pusetreg_show, pusetreg_store),
|
||||
__ATTR(pdsetreg, 0644, pdsetreg_show, pdsetreg_store),
|
||||
__ATTR(rdcorereg, 0644, rdcorereg_show, rdcorereg_store),
|
||||
__ATTR(wrcorereg, 0644, wrcorereg_show, wrcorereg_store),
|
||||
__ATTR(wrregvbusclk, 0644, wrregvbusclk_show, wrregvbusclk_store),
|
||||
__ATTR(wrregcnnclk, 0644, wrregcnnclk_show, wrregcnnclk_store),
|
||||
__ATTR(wrreglmt, 0644, wrreglmt_show, wrreglmt_store),
|
||||
};
|
||||
|
||||
static int create_ics_attrs(struct class *class)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
int ret = 0;
|
||||
|
||||
for (i = 0; i < (sizeof(ics_attrs)/sizeof(struct class_attribute)); i++) {
|
||||
ret = class_create_file(class, &ics_attrs[i]);
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void remove_ics_attrs(struct class *class)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
for (i = 0; i < (sizeof(ics_attrs)/sizeof(struct class_attribute)); i++) {
|
||||
class_remove_file(class, &ics_attrs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static int __init ics_debug_init(void) {
|
||||
int ret = 0;
|
||||
printk(KERN_ERR"[%s:%d], test begin\n", __FUNCTION__, __LINE__);
|
||||
|
||||
ics_class = class_create(THIS_MODULE, CLASS_NAME);
|
||||
if (IS_ERR(ics_class)) {
|
||||
printk(KERN_ERR"[%s:%d], class create error!\n", __FUNCTION__, __LINE__);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
ret = create_ics_attrs(ics_class);
|
||||
if(ret < 0) {
|
||||
class_destroy(ics_class);
|
||||
printk(KERN_ERR"[%s:%d], create_ics_attrs error!\n", __FUNCTION__, __LINE__);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
ics_adapter = get_ipu_adapter();
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static void __exit ics_debug_exit(void) {
|
||||
printk(KERN_ERR"[%s:%d], test end\n", __FUNCTION__, __LINE__);
|
||||
remove_ics_attrs(ics_class);
|
||||
class_destroy(ics_class);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
module_init(ics_debug_init);
|
||||
module_exit(ics_debug_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Hisilicon");
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef __ICS_DEBUG_H__
|
||||
#define __ICS_DEBUG_H__
|
||||
|
||||
#include "ics_debug_proxy.h"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,77 @@
|
||||
#include "ipu_clock.h"
|
||||
#include "ipu_smmu_drv.h"
|
||||
#include "ics_debug_proxy.h"
|
||||
|
||||
struct ioctl_out_params {
|
||||
bool ret_directly;
|
||||
void *memory_node;
|
||||
//TODO: add more out params here
|
||||
};
|
||||
|
||||
extern struct cambricon_ipu_private *adapter;
|
||||
extern int regulator_ip_vipu_enable(void);
|
||||
extern int regulator_ip_vipu_disable(void);
|
||||
extern void ipu_reset_proc(unsigned int addr);
|
||||
extern void ipu_interrupt_init(void);
|
||||
extern long ipu_set_profile(struct cambricon_ipu_private *, unsigned long, struct ioctl_out_params *);
|
||||
|
||||
int call_regulator_ip_vipu_enable(void)
|
||||
{
|
||||
return regulator_ip_vipu_enable();
|
||||
}
|
||||
EXPORT_SYMBOL(call_regulator_ip_vipu_enable);
|
||||
|
||||
int call_regulator_ip_vipu_disable(void)
|
||||
{
|
||||
return regulator_ip_vipu_disable();
|
||||
}
|
||||
EXPORT_SYMBOL(call_regulator_ip_vipu_disable);
|
||||
|
||||
void call_ipu_reset_proc(unsigned int addr)
|
||||
{
|
||||
ipu_reset_proc(addr);
|
||||
}
|
||||
EXPORT_SYMBOL(call_ipu_reset_proc);
|
||||
|
||||
void call_ipu_interrupt_init(void)
|
||||
{
|
||||
ipu_interrupt_init();
|
||||
}
|
||||
EXPORT_SYMBOL(call_ipu_interrupt_init);
|
||||
|
||||
void * get_ipu_adapter(void)
|
||||
{
|
||||
return adapter;
|
||||
}
|
||||
EXPORT_SYMBOL(get_ipu_adapter);
|
||||
|
||||
int call_ipu_clock_start(void *clock)
|
||||
{
|
||||
return ipu_clock_start(clock);
|
||||
}
|
||||
EXPORT_SYMBOL(call_ipu_clock_start);
|
||||
|
||||
int call_ipu_clock_set_rate(void *clock, unsigned int clock_rate)
|
||||
{
|
||||
return ipu_clock_set_rate(clock, clock_rate);
|
||||
}
|
||||
EXPORT_SYMBOL(call_ipu_clock_set_rate);
|
||||
|
||||
void call_ipu_clock_stop(void *clock)
|
||||
{
|
||||
ipu_clock_stop(clock);
|
||||
}
|
||||
EXPORT_SYMBOL(call_ipu_clock_stop);
|
||||
|
||||
void call_ipu_smmu_init(unsigned long ttbr0, unsigned long smmu_rw_err_phy_addr, bool port_sel, bool hardware_start)
|
||||
{
|
||||
ipu_smmu_init(ttbr0, smmu_rw_err_phy_addr, port_sel, hardware_start);
|
||||
}
|
||||
EXPORT_SYMBOL(call_ipu_smmu_init);
|
||||
|
||||
void call_ipu_set_profile(unsigned long profile)
|
||||
{
|
||||
ipu_set_profile(0, profile, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(call_ipu_set_profile);
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef __ICS_DEBUG_PROXY_H__
|
||||
#define __ICS_DEBUG_PROXY_H__
|
||||
|
||||
#include "cambricon_ipu.h"
|
||||
|
||||
int call_regulator_ip_vipu_enable(void);
|
||||
int call_regulator_ip_vipu_disable(void);
|
||||
void call_ipu_reset_proc(unsigned int addr);
|
||||
void call_ipu_interrupt_init(void);
|
||||
void * get_ipu_adapter(void);
|
||||
int call_ipu_clock_start(void *clk);
|
||||
int call_ipu_clock_set_rate(void *clock, unsigned int clock_rate);
|
||||
void call_ipu_clock_stop(void *clock);
|
||||
void call_ipu_smmu_init(unsigned long ttbr0, unsigned long smmu_rw_err_phy_addr, bool port_sel, bool hardware_start);
|
||||
void call_ipu_set_profile(unsigned long profile);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,233 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include "ipu_clock.h"
|
||||
// #include "ipu_mntn.h"
|
||||
#include "cambricon_ipu.h"
|
||||
|
||||
// #define CONFIG_IPU_CLOCK_CONTROL
|
||||
|
||||
extern struct cambricon_ipu_private *adapter;
|
||||
|
||||
/* this func use mutex, for interface only, and SHOULD NOT be called by other ipu_clock functions */
|
||||
int ipu_clock_init(struct device *dev, struct ics_clock *clk, bool lpm3_set_vcodecbus)
|
||||
{
|
||||
int property_rd;
|
||||
struct device_node *node;
|
||||
|
||||
mutex_lock(&clk->clk_mutex);
|
||||
clk->lpm3_set_vcodecbus = lpm3_set_vcodecbus;
|
||||
|
||||
/* get clock of "clk-ics" from CLK API */
|
||||
clk->ipu_clk_ptr = devm_clk_get(dev, "clk-ics");
|
||||
|
||||
if (IS_ERR_OR_NULL(clk->ipu_clk_ptr)) {
|
||||
printk(KERN_ERR"[%s]: IPU_ERROR:get clock failed, ipu_clk_ptr is %pK\n", __func__, clk->ipu_clk_ptr);
|
||||
mutex_unlock(&clk->clk_mutex);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
clk->vcodecbus_clk_ptr = devm_clk_get(dev, "clk_vcodecbus");
|
||||
printk(KERN_DEBUG "[%s]: IPU_DEBUG vcodecbus_clk_ptr is %pK\n", __func__, clk->vcodecbus_clk_ptr);
|
||||
#ifdef CONFIG_HISI_IPU_SET_VCODECBUS
|
||||
if (IS_ERR_OR_NULL(clk->vcodecbus_clk_ptr)) {
|
||||
printk(KERN_ERR"[%s]: IPU_ERROR:get clock failed, vcodecbus_clk_ptr is %pK\n", __func__, clk->vcodecbus_clk_ptr);
|
||||
mutex_unlock(&clk->clk_mutex);
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
|
||||
node = of_find_node_by_name(dev->of_node, "ipu-and-vcodecbus-clock-rate");
|
||||
if(!node) {
|
||||
printk(KERN_ERR"[%s]: IPU_ERROR:find clock node error\n", __func__);
|
||||
mutex_unlock(&clk->clk_mutex);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
property_rd = of_property_read_u32(node, "start-rate", &clk->start_rate);
|
||||
property_rd |= of_property_read_u32(node, "stop-rate", &clk->stop_rate);
|
||||
property_rd |= of_property_read_u32(node, "ipu-low", &clk->ipu_low);
|
||||
property_rd |= of_property_read_u32(node, "ipu-middle", &clk->ipu_middle);
|
||||
property_rd |= of_property_read_u32(node, "ipu-high", &clk->ipu_high);
|
||||
property_rd |= of_property_read_u32(node, "ipu-low-temperature", &clk->ipu_low_temperature);
|
||||
property_rd |= of_property_read_u32(node, "vcodecbus-low", &clk->vcodecbus_low);
|
||||
property_rd |= of_property_read_u32(node, "vcodecbus-middle", &clk->vcodecbus_middle);
|
||||
property_rd |= of_property_read_u32(node, "vcodecbus-high", &clk->vcodecbus_high);
|
||||
property_rd |= of_property_read_u32(node, "vcodecbus-default", &clk->vcodecbus_default);
|
||||
property_rd |= of_property_read_u32(node, "vcodecbus-high2default", &clk->vcodecbus_high2default);
|
||||
if (property_rd) {
|
||||
printk(KERN_ERR"[%s]: IPU_ERROR:read property of clock error\n", __func__);
|
||||
mutex_unlock(&clk->clk_mutex);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ES_VDEC_LOW_FREQ
|
||||
clk->vcodecbus_high = clk->vcodecbus_middle;
|
||||
clk->ipu_high = clk->ipu_middle;
|
||||
clk->start_rate = clk->ipu_middle;
|
||||
#endif
|
||||
|
||||
printk(KERN_DEBUG"[%s]: get clk rate done, start clk rate:%u, stop clk rate:%u\n",
|
||||
__func__, clk->start_rate, clk->stop_rate);
|
||||
|
||||
clk->curr_rate = IPU_CLOCK_UNSET;
|
||||
mutex_unlock(&clk->clk_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ipu_clock_set(struct ics_clock *clk, unsigned int new_rate)
|
||||
{
|
||||
int ret;
|
||||
unsigned int target_rate = new_rate;
|
||||
|
||||
if (new_rate == clk->curr_rate) {
|
||||
printk(KERN_ERR"[%s]: IPU_WARN:set some IPU clock rate %d, ignored\n", __func__, target_rate);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IPU_CLOCK_CONTROL
|
||||
if (clk->ipu_high == target_rate) {
|
||||
/* for HIGH, set IPU clock to HIGH */
|
||||
ret = clk_set_rate(clk->ipu_clk_ptr, (unsigned long)target_rate);
|
||||
if (ret) {
|
||||
/* in low temperature, clk set rate to HIGH will fail, in this case try to set rate to another rate */
|
||||
printk(KERN_ERR"[%s]: IPU_ERROR:set ipu rate %d fail (possible in low temperature), ret:%d, try to set %d\n",
|
||||
__func__, target_rate, ret, clk->ipu_low_temperature);
|
||||
target_rate = clk->ipu_low_temperature;
|
||||
ret = clk_set_rate(clk->ipu_clk_ptr, (unsigned long)target_rate);
|
||||
if (ret) {
|
||||
printk(KERN_ERR"[%s]: IPU_ERROR:set ipu rate %d fail, ret:%d\n", __func__, target_rate, ret);
|
||||
rdr_system_error((unsigned int)MODID_NPU_EXC_SET_BACK_CLOCK_FAIL, 0, 0);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
#ifdef CONFIG_HISI_IPU_SET_VCODECBUS
|
||||
if (!clk->lpm3_set_vcodecbus) {
|
||||
/* for HIGH set IPU rate ok, set VCODECBUS to HIGH */
|
||||
ret = clk_set_rate(clk->vcodecbus_clk_ptr, clk->vcodecbus_high);
|
||||
if (ret) {
|
||||
printk(KERN_ERR"[%s]: IPU_ERROR:set vcodec rate %d fail, ret:%d, ignore\n", __func__, clk->vcodecbus_high, ret);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
#ifdef CONFIG_HISI_IPU_SET_VCODECBUS
|
||||
/* for MIDDLE or LOW, set VCODECBUS to default if necessary (when alter from HIGH) */
|
||||
if (!clk->lpm3_set_vcodecbus && clk->ipu_high == clk->curr_rate) {
|
||||
/* set vcodec bus to "VCODECBUS_CLOCK_DEFAULT", which is used as the default rate for VENC/VDEC */
|
||||
ret = clk_set_rate(clk->vcodecbus_clk_ptr, clk->vcodecbus_high2default);
|
||||
if (ret) {
|
||||
printk(KERN_ERR"[%s]: IPU_ERROR:set vcodec rate %d fail, ret:%d, ignore\n", __func__, clk->vcodecbus_high2default, ret);
|
||||
}
|
||||
|
||||
ret = clk_set_rate(clk->vcodecbus_clk_ptr, clk->vcodecbus_default);
|
||||
if (ret) {
|
||||
printk(KERN_ERR"[%s]: IPU_ERROR:set vcodec rate %d fail, ret:%d, ignore\n", __func__, clk->vcodecbus_default, ret);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = clk_set_rate(clk->ipu_clk_ptr, (unsigned long)target_rate);
|
||||
if (ret) {
|
||||
/* in low temperature, clk set rate to HIGH will fail, in this case try to set rate to MIDDLE */
|
||||
printk(KERN_ERR"[%s]: IPU_ERROR:set ipu rate %d fail, ret:%d\n", __func__, target_rate, ret);
|
||||
rdr_system_error((unsigned int)MODID_NPU_EXC_SET_CLOCK_FAIL, 0, 0);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HISI_IPU_SET_VCODECBUS
|
||||
printk(KERN_ERR"[%s]: IPU_NOTE: set clock done, ipu clock(try/actually/clk_get)=%d/%d/%ld, vcodecbus clock=%ld\n",
|
||||
__func__, new_rate, target_rate, clk_get_rate(clk->ipu_clk_ptr), clk_get_rate(clk->vcodecbus_clk_ptr));
|
||||
#else
|
||||
printk(KERN_ERR"[%s]: IPU_NOTE: set clock done, ipu clock(try/actually/clk_get)=%d/%d/%ld\n",
|
||||
__func__, new_rate, target_rate, clk_get_rate(clk->ipu_clk_ptr));
|
||||
#endif
|
||||
|
||||
#endif // CONFIG_IPU_CLOCK_CONTROL
|
||||
clk->curr_rate = target_rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* this func use mutex, for interface only, and SHOULD NOT be called by other ipu_clock functions */
|
||||
int ipu_clock_start(struct ics_clock *clk)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&clk->clk_mutex);
|
||||
|
||||
#ifdef CONFIG_IPU_CLOCK_CONTROL
|
||||
/* WARNING: clk_prepare_enable should NOT be called in interrupt because it contains mutex.
|
||||
If needed in furture, use API: clk_prepare and clk_enable instead of clk_prepare_enable
|
||||
in interrupt functions. */
|
||||
ret = clk_prepare_enable(clk->ipu_clk_ptr);
|
||||
#endif
|
||||
|
||||
if (ret) {
|
||||
printk(KERN_ERR"[%s]: IPU_ERROR:clk prepare enable failed,ret=%d\n", __func__, ret);
|
||||
mutex_unlock(&clk->clk_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* NOTE: here need not call "clk_prepare_enable(clk->vcodecbus_clk_ptr)" because because it is used by both IPU and VCODEC
|
||||
process can guarentee it!! */
|
||||
|
||||
clk->curr_rate = IPU_CLOCK_UNSET;
|
||||
ret = ipu_clock_set(clk, clk->start_rate);
|
||||
if (ret) {
|
||||
printk(KERN_ERR"[%s]: IPU_ERROR:ipu_clock_set_rate failed,ret=%d\n", __func__, ret);
|
||||
mutex_unlock(&clk->clk_mutex);
|
||||
return ret;
|
||||
}
|
||||
mutex_unlock(&clk->clk_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* this func use mutex, for interface only, and SHOULD NOT be called by other ipu_clock functions */
|
||||
int ipu_clock_set_start_rate(struct ics_clock *clk, unsigned int new_rate)
|
||||
{
|
||||
mutex_lock(&clk->clk_mutex);
|
||||
|
||||
if (clk->ipu_high == new_rate ||
|
||||
clk->ipu_middle == new_rate ||
|
||||
clk->ipu_low == new_rate) {
|
||||
|
||||
/* vote voltage hold lock if neccessary */
|
||||
clk->start_rate = new_rate;
|
||||
|
||||
mutex_unlock(&clk->clk_mutex);
|
||||
return 0;
|
||||
} else {
|
||||
printk(KERN_ERR"[%s]: IPU_ERROR:invalid start rate=%u\n", __func__, new_rate);
|
||||
mutex_unlock(&clk->clk_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* this func use mutex, for interface only, and SHOULD NOT be called by other ipu_clock functions */
|
||||
int ipu_clock_set_rate(struct ics_clock *clk, unsigned int new_rate)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&clk->clk_mutex);
|
||||
ret = ipu_clock_set(clk, new_rate);
|
||||
mutex_unlock(&clk->clk_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* this func use mutex, for interface only, and SHOULD NOT be called by other ipu_clock functions */
|
||||
void ipu_clock_stop(struct ics_clock *clk)
|
||||
{
|
||||
mutex_lock(&clk->clk_mutex);
|
||||
|
||||
#ifdef CONFIG_IPU_CLOCK_CONTROL
|
||||
clk_disable_unprepare(clk->ipu_clk_ptr);
|
||||
#endif // CONFIG_IPU_CLOCK_CONTROL
|
||||
|
||||
/* NOTE: here need not call "clk_disable_unprepare(clk->vcodecbus_clk_ptr)" because it is used by both IPU and VCODEC
|
||||
process can guarentee it!! */
|
||||
mutex_unlock(&clk->clk_mutex);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/* Module internals
|
||||
*
|
||||
* Copyright (C) 2017 Hisilicon, Inc. All Rights Reserved.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are the
|
||||
* copyrighted works and confidential proprietary information of
|
||||
* Hisilicon Inc. and its licensors, and are licensed to the recipient
|
||||
* under the terms of a separate license agreement. They may be
|
||||
* adapted and modified by bona fide purchasers under the terms of the
|
||||
* separate license agreement for internal use, but no adapted or
|
||||
* modified version may be disclosed or distributed to third parties
|
||||
* in any manner, medium, or form, in whole or in part, without the
|
||||
* prior written consent of Hisilicon Inc.
|
||||
*/
|
||||
|
||||
#ifndef _IPU_CLOCK_H
|
||||
#define _IPU_CLOCK_H
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#define IPU_CLOCK_UNSET (0)
|
||||
|
||||
struct ics_clock {
|
||||
struct clk *ipu_clk_ptr;
|
||||
struct clk *vcodecbus_clk_ptr;
|
||||
unsigned int ipu_low;
|
||||
unsigned int ipu_middle;
|
||||
unsigned int ipu_high;
|
||||
unsigned int ipu_low_temperature;
|
||||
unsigned int vcodecbus_low;
|
||||
unsigned int vcodecbus_middle;
|
||||
unsigned int vcodecbus_high;
|
||||
unsigned int vcodecbus_default;
|
||||
unsigned int vcodecbus_high2default;
|
||||
unsigned int start_rate;
|
||||
unsigned int curr_rate;
|
||||
unsigned int stop_rate;
|
||||
struct mutex clk_mutex;
|
||||
bool lpm3_set_vcodecbus;
|
||||
};
|
||||
|
||||
extern int ipu_clock_init(struct device *dev, struct ics_clock *clk, bool lpm3_set_vcodecbus);
|
||||
extern int ipu_clock_start(struct ics_clock *clk);
|
||||
extern void ipu_clock_stop(struct ics_clock *clk);
|
||||
extern int ipu_clock_set_rate(struct ics_clock *clk, unsigned int new_rate);
|
||||
extern int ipu_clock_set_start_rate(struct ics_clock *clk, unsigned int new_rate);
|
||||
#endif
|
||||
@@ -0,0 +1,433 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/errno.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/compiler.h>
|
||||
#include <mntn_subtype_exception.h>
|
||||
#include <mntn_public_interface.h>
|
||||
|
||||
#include "ipu_mntn.h"
|
||||
#include "ipu_smmu_drv.h"
|
||||
#include "cambricon_ipu.h"
|
||||
|
||||
struct rdr_exception_info_s ipu_excetption_info[] = {
|
||||
{
|
||||
.e_modid = (u32)MODID_NPU_EXC_DEAD,
|
||||
.e_modid_end = (u32)MODID_NPU_EXC_DEAD,
|
||||
.e_process_priority = RDR_ERR,
|
||||
.e_reboot_priority = RDR_REBOOT_NO,
|
||||
.e_notify_core_mask = RDR_NPU,
|
||||
.e_reset_core_mask = RDR_NPU,
|
||||
.e_from_core = RDR_NPU,
|
||||
.e_reentrant = (u32)RDR_REENTRANT_DISALLOW,
|
||||
.e_exce_type = NPU_S_EXCEPTION,
|
||||
.e_exce_subtype = NPU_EXC_DEAD,
|
||||
.e_upload_flag = (u32)RDR_UPLOAD_YES,
|
||||
.e_from_module = "NPU",
|
||||
.e_desc = "NPU_EXC_DEAD",
|
||||
},
|
||||
{
|
||||
.e_modid = (u32)MODID_NPU_EXC_SET_BACK_CLOCK_FAIL,
|
||||
.e_modid_end = (u32)MODID_NPU_EXC_SET_BACK_CLOCK_FAIL,
|
||||
.e_process_priority = RDR_ERR,
|
||||
.e_reboot_priority = RDR_REBOOT_NO,
|
||||
.e_notify_core_mask = RDR_NPU,
|
||||
.e_reset_core_mask = RDR_NPU,
|
||||
.e_from_core = RDR_NPU,
|
||||
.e_reentrant = (u32)RDR_REENTRANT_DISALLOW,
|
||||
.e_exce_type = NPU_S_EXCEPTION,
|
||||
.e_exce_subtype = NPU_SET_BACK_CLOCK_FAIL,
|
||||
.e_upload_flag = (u32)RDR_UPLOAD_YES,
|
||||
.e_from_module = "NPU",
|
||||
.e_desc = "NPU_SET_BACK_CLOCK_FAIL",
|
||||
},
|
||||
{
|
||||
.e_modid = (u32)MODID_NPU_EXC_SET_CLOCK_FAIL,
|
||||
.e_modid_end = (u32)MODID_NPU_EXC_SET_CLOCK_FAIL,
|
||||
.e_process_priority = RDR_ERR,
|
||||
.e_reboot_priority = RDR_REBOOT_NO,
|
||||
.e_notify_core_mask = RDR_NPU,
|
||||
.e_reset_core_mask = RDR_NPU,
|
||||
.e_from_core = RDR_NPU,
|
||||
.e_reentrant = (u32)RDR_REENTRANT_DISALLOW,
|
||||
.e_exce_type = NPU_S_EXCEPTION,
|
||||
.e_exce_subtype = NPU_SET_CLOCK_FAIL,
|
||||
.e_upload_flag = (u32)RDR_UPLOAD_YES,
|
||||
.e_from_module = "NPU",
|
||||
.e_desc = "NPU_SET_CLOCK_FAIL",
|
||||
},
|
||||
{
|
||||
.e_modid = (u32)MODID_NPU_EXC_SET_POWER_UP_FAIL,
|
||||
.e_modid_end = (u32)MODID_NPU_EXC_SET_POWER_UP_FAIL,
|
||||
.e_process_priority = RDR_ERR,
|
||||
.e_reboot_priority = RDR_REBOOT_NO,
|
||||
.e_notify_core_mask = RDR_NPU,
|
||||
.e_reset_core_mask = RDR_NPU,
|
||||
.e_from_core = RDR_NPU,
|
||||
.e_reentrant = (u32)RDR_REENTRANT_DISALLOW,
|
||||
.e_exce_type = NPU_S_EXCEPTION,
|
||||
.e_exce_subtype = NPU_POWER_UP_FAIL,
|
||||
.e_upload_flag = (u32)RDR_UPLOAD_YES,
|
||||
.e_from_module = "NPU",
|
||||
.e_desc = "NPU_POWER_UP_FAIL",
|
||||
},
|
||||
{
|
||||
.e_modid = (u32)MODID_NPU_EXC_SET_POWER_UP_STATUS_FAULT,
|
||||
.e_modid_end = (u32)MODID_NPU_EXC_SET_POWER_UP_STATUS_FAULT,
|
||||
.e_process_priority = RDR_ERR,
|
||||
.e_reboot_priority = RDR_REBOOT_NO,
|
||||
.e_notify_core_mask = RDR_NPU,
|
||||
.e_reset_core_mask = RDR_NPU,
|
||||
.e_from_core = RDR_NPU,
|
||||
.e_reentrant = (u32)RDR_REENTRANT_DISALLOW,
|
||||
.e_exce_type = NPU_S_EXCEPTION,
|
||||
.e_exce_subtype = NPU_POWER_UP_STA_FAULT,
|
||||
.e_upload_flag = (u32)RDR_UPLOAD_YES,
|
||||
.e_from_module = "NPU",
|
||||
.e_desc = "NPU_POWER_UP_STA_FAULT",
|
||||
},
|
||||
{
|
||||
.e_modid = (u32)MODID_NPU_EXC_SET_POWER_DOWN_FAIL,
|
||||
.e_modid_end = (u32)MODID_NPU_EXC_SET_POWER_DOWN_FAIL,
|
||||
.e_process_priority = RDR_ERR,
|
||||
.e_reboot_priority = RDR_REBOOT_NO,
|
||||
.e_notify_core_mask = RDR_NPU,
|
||||
.e_reset_core_mask = RDR_NPU,
|
||||
.e_from_core = RDR_NPU,
|
||||
.e_reentrant = (u32)RDR_REENTRANT_DISALLOW,
|
||||
.e_exce_type = NPU_S_EXCEPTION,
|
||||
.e_exce_subtype = NPU_POWER_DOWN_FAIL,
|
||||
.e_upload_flag = (u32)RDR_UPLOAD_YES,
|
||||
.e_from_module = "NPU",
|
||||
.e_desc = "NPU_POWER_DOWN_FAIL",
|
||||
},
|
||||
{
|
||||
.e_modid = (u32)MODID_NPU_EXC_INTERRUPT_ABNORMAL,
|
||||
.e_modid_end = (u32)MODID_NPU_EXC_INTERRUPT_ABNORMAL,
|
||||
.e_process_priority = RDR_ERR,
|
||||
.e_reboot_priority = RDR_REBOOT_NO,
|
||||
.e_notify_core_mask = RDR_NPU,
|
||||
.e_reset_core_mask = RDR_NPU,
|
||||
.e_from_core = RDR_NPU,
|
||||
.e_reentrant = (u32)RDR_REENTRANT_DISALLOW,
|
||||
.e_exce_type = NPU_S_EXCEPTION,
|
||||
.e_exce_subtype = NPU_INTERRUPT_ABNORMAL,
|
||||
.e_upload_flag = (u32)RDR_UPLOAD_YES,
|
||||
.e_from_module = "NPU",
|
||||
.e_desc = "NPU_INTERRUPT_ABNORMAL",
|
||||
}
|
||||
};
|
||||
|
||||
struct work_struct ipu_dump_work;
|
||||
struct workqueue_struct *ipu_mntn_rdr_wq;
|
||||
|
||||
struct ipu_mntn_info_s ipu_mntn_info;
|
||||
struct ipu_reg_info_s ipu_reg_info;
|
||||
|
||||
extern struct cambricon_ipu_private *adapter;
|
||||
|
||||
/********************************************************************
|
||||
Description: ipu_mntn_copy_reg_to_bbox
|
||||
input: char *src_addr, unsigned int* offset, unsigned int len
|
||||
output: NA
|
||||
return: void
|
||||
********************************************************************/
|
||||
static int ipu_mntn_copy_reg_to_bbox(char *src_addr, unsigned int len)
|
||||
{
|
||||
unsigned int temp_offset = 0;
|
||||
|
||||
if ((NULL == src_addr) || (0 == len)) {
|
||||
printk(KERN_ERR"[%s]:IPU_ERROR:Input parameter is error!\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
temp_offset = ipu_mntn_info.bbox_addr_offset + len;
|
||||
//ipu_bbox alloc size 64k
|
||||
if (temp_offset > 0x10000) {
|
||||
printk(KERN_ERR"[%s]:IPU_ERROR:Copy log to bbox size is error! temp_offset=%d\n", __func__, temp_offset);
|
||||
temp_offset = 0;
|
||||
ipu_mntn_info.bbox_addr_offset = 0;
|
||||
return -ENOMEM ;
|
||||
}
|
||||
|
||||
memcpy(((char*)ipu_mntn_info.rdr_addr + ipu_mntn_info.bbox_addr_offset), src_addr, len);
|
||||
ipu_mntn_info.bbox_addr_offset = temp_offset;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
/********************************************************************
|
||||
Description: ipu_mntn_write_adapter_info
|
||||
input: char *file_path
|
||||
output: NA
|
||||
return: void
|
||||
********************************************************************/
|
||||
static void ipu_mntn_write_adapter_info(void)
|
||||
{
|
||||
char log_buf[IPU_LINE_MAX + 1] = {0};
|
||||
|
||||
snprintf(log_buf, IPU_LINE_MAX, "npu_status=%d, ttbr0=%lx, inst_set=%d, offchip{set=%x, base=%x}, last_computed_task=%ld.\r\n",
|
||||
adapter->ipu_power_up,
|
||||
adapter->smmu_ttbr0,
|
||||
adapter->boot_inst_set.boot_inst_recorded_is_config,
|
||||
adapter->boot_inst_set.access_ddr_addr_is_config,
|
||||
adapter->boot_inst_set.ipu_access_ddr_addr,
|
||||
adapter->computed_task_cnt);
|
||||
|
||||
ipu_mntn_copy_reg_to_bbox(log_buf, strlen(log_buf));
|
||||
|
||||
return;
|
||||
}
|
||||
/********************************************************************
|
||||
Description: ipu_mntn_write_peri_reg_info
|
||||
input: char *file_path
|
||||
output: NA
|
||||
return: void
|
||||
********************************************************************/
|
||||
static void ipu_mntn_write_peri_reg_info(void)
|
||||
{
|
||||
char log_buf[IPU_LINE_MAX + 1] = {0};
|
||||
|
||||
snprintf(log_buf, IPU_LINE_MAX, "peri_stat=%x, ppll_select=%x, power_stat=%x, power_ack=%x, reset_stat=%x, perclken=%x, perstat=%x.\r\n",
|
||||
ipu_reg_info.peri_reg.peri_stat,
|
||||
ipu_reg_info.peri_reg.ppll_select,
|
||||
ipu_reg_info.peri_reg.power_stat,
|
||||
ipu_reg_info.peri_reg.power_ack,
|
||||
ipu_reg_info.peri_reg.reset_stat,
|
||||
ipu_reg_info.peri_reg.perclken0,
|
||||
ipu_reg_info.peri_reg.perstat0);
|
||||
|
||||
ipu_mntn_copy_reg_to_bbox(log_buf, strlen(log_buf));
|
||||
return;
|
||||
}
|
||||
/********************************************************************
|
||||
Description: ipu_mntn_write_mstr_reg_info
|
||||
input: char *file_path
|
||||
output: NA
|
||||
return: void
|
||||
********************************************************************/
|
||||
static void ipu_mntn_write_mstr_reg_info(void)
|
||||
{
|
||||
char log_buf[IPU_BUF_LEN_MAX + 1] = {0};
|
||||
|
||||
snprintf(log_buf, IPU_BUF_LEN_MAX, "RD_BITMAP=%x, WR_BITMAP=%x, rd_cmd_total_cnt[0-3]={%x, %x, %x}, wr_cmd_total_cnt=%x\n",
|
||||
ipu_reg_info.mstr_reg.rd_bitmap,
|
||||
ipu_reg_info.mstr_reg.wr_bitmap,
|
||||
ipu_reg_info.mstr_reg.rd_cmd_total_cnt0,
|
||||
ipu_reg_info.mstr_reg.rd_cmd_total_cnt0,
|
||||
ipu_reg_info.mstr_reg.rd_cmd_total_cnt2,
|
||||
ipu_reg_info.mstr_reg.wr_cmd_total_cnt);
|
||||
|
||||
ipu_mntn_copy_reg_to_bbox(log_buf, strlen(log_buf));
|
||||
|
||||
return;
|
||||
}
|
||||
/********************************************************************
|
||||
Description: ipu_mntn_write_reg_log
|
||||
input: void
|
||||
output: NA
|
||||
return: void
|
||||
********************************************************************/
|
||||
static void ipu_mntn_write_reg_log(void)
|
||||
{
|
||||
switch (ipu_mntn_info.dump_info.modid) {
|
||||
case MODID_NPU_EXC_DEAD: //lint !e650
|
||||
ipu_mntn_write_adapter_info();
|
||||
ipu_mntn_write_peri_reg_info();
|
||||
ipu_mntn_write_mstr_reg_info();
|
||||
#ifdef CONFIG_HUAWEI_DSM
|
||||
ipu_mntn_copy_reg_to_bbox(register_info, strlen(register_info));
|
||||
#endif
|
||||
break;
|
||||
|
||||
case MODID_NPU_EXC_SET_BACK_CLOCK_FAIL: //lint !e650
|
||||
case MODID_NPU_EXC_SET_CLOCK_FAIL: //lint !e650
|
||||
case MODID_NPU_EXC_SET_POWER_UP_FAIL: //lint !e650
|
||||
case MODID_NPU_EXC_SET_POWER_UP_STATUS_FAULT: //lint !e650
|
||||
case MODID_NPU_EXC_SET_POWER_DOWN_FAIL: //lint !e650
|
||||
case MODID_NPU_EXC_INTERRUPT_ABNORMAL: //lint !e650
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
/********************************************************************
|
||||
Description: ipu_mntn_rdr_dump
|
||||
input: modid: module id
|
||||
etype:exception type
|
||||
coreid: core id
|
||||
pathname: log path
|
||||
pfn_cb: callback function
|
||||
output: NA
|
||||
return: NA
|
||||
********************************************************************/
|
||||
static void ipu_mntn_rdr_dump(u32 modid, u32 etype, u64 coreid, char *pathname, pfn_cb_dump_done pfn_cb)
|
||||
{
|
||||
if (NULL == pathname) {
|
||||
printk(KERN_ERR"[%s]:IPU_ERROR:pathname is empty\n", __func__);
|
||||
return;
|
||||
}
|
||||
ipu_mntn_info.dump_info.modid = modid;
|
||||
ipu_mntn_info.dump_info.coreid = coreid;
|
||||
ipu_mntn_info.dump_info.pathname = pathname;
|
||||
ipu_mntn_info.dump_info.cb = pfn_cb;
|
||||
ipu_mntn_info.bbox_addr_offset = 0;
|
||||
queue_work(ipu_mntn_rdr_wq, &ipu_dump_work);
|
||||
return;
|
||||
}
|
||||
/********************************************************************
|
||||
Description: ipu_mntn_rdr_reset
|
||||
input: modid:module id
|
||||
etype:exception type
|
||||
coreid:core id
|
||||
output: NA
|
||||
return: NA
|
||||
********************************************************************/
|
||||
static void ipu_mntn_rdr_reset(u32 modid, u32 etype, u64 coreid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
/********************************************************************
|
||||
Description: ipu_mntn_dump_work
|
||||
input: struct work_struct *work
|
||||
output: NA
|
||||
return: NA
|
||||
********************************************************************/
|
||||
static void ipu_mntn_dump_work(struct work_struct *work)
|
||||
{
|
||||
ipu_mntn_write_reg_log();
|
||||
|
||||
if (ipu_mntn_info.dump_info.cb) {
|
||||
ipu_mntn_info.dump_info.cb(ipu_mntn_info.dump_info.modid, ipu_mntn_info.dump_info.coreid);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
/********************************************************************
|
||||
Description: ipu_mntn_register_exception
|
||||
input: NA
|
||||
output: NA
|
||||
return: int
|
||||
********************************************************************/
|
||||
static int ipu_mntn_register_exception(void)
|
||||
{
|
||||
int ret;
|
||||
unsigned int size;
|
||||
unsigned long index;
|
||||
|
||||
size = sizeof(ipu_excetption_info)/sizeof(struct rdr_exception_info_s);
|
||||
for (index = 0; index < size; index++) {
|
||||
/* error return 0, ok return modid */
|
||||
ret = rdr_register_exception(&ipu_excetption_info[index]);
|
||||
if (!ret) {
|
||||
printk(KERN_ERR"[%s]:IPU_ERROR:rdr_register_exception is failed! index=%ld ret=%d\n", __func__, index, ret);
|
||||
return -EINTR;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/********************************************************************
|
||||
Description: register ipu dump and reset function
|
||||
input: NA
|
||||
output: NA
|
||||
return: int
|
||||
********************************************************************/
|
||||
static int ipu_mntn_register_core(void)
|
||||
{
|
||||
int ret;
|
||||
struct rdr_module_ops_pub s_soc_ops;
|
||||
|
||||
s_soc_ops.ops_dump = ipu_mntn_rdr_dump;
|
||||
s_soc_ops.ops_reset = ipu_mntn_rdr_reset;
|
||||
/* register ipu core dump and reset function */
|
||||
ret = rdr_register_module_ops((u64)RDR_NPU, &s_soc_ops, &ipu_mntn_info.ipu_ret_info);
|
||||
if (ret != 0) {
|
||||
printk(KERN_ERR"[%s]:IPU_ERROR:rdr_register_module_ops is failed! ret=0x%08x\n", __func__, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/********************************************************************
|
||||
Description: init ipu addr function
|
||||
input: NA
|
||||
output: NA
|
||||
return: int
|
||||
********************************************************************/
|
||||
static int ipu_mntn_addr_map(void)
|
||||
{
|
||||
ipu_mntn_info.rdr_addr = hisi_bbox_map((phys_addr_t)ipu_mntn_info.ipu_ret_info.log_addr, ipu_mntn_info.ipu_ret_info.log_len);
|
||||
if (!ipu_mntn_info.rdr_addr) {
|
||||
printk(KERN_ERR"[%s]:IPU_ERROR:hisi_bbox_map is failed!\n", __func__);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/********************************************************************
|
||||
Description: ipu_mntn_rdr_resource_init
|
||||
input: NA
|
||||
output: NA
|
||||
return: int
|
||||
********************************************************************/
|
||||
static int ipu_mntn_rdr_resource_init(void)
|
||||
{
|
||||
ipu_mntn_rdr_wq = create_singlethread_workqueue("ipu_mntn_rdr_wq");
|
||||
if (!ipu_mntn_rdr_wq) {
|
||||
printk(KERN_ERR"[%s]:IPU_ERROR:Create_singlethread_workqueue is failed!\n", __func__);
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
INIT_WORK(&ipu_dump_work, ipu_mntn_dump_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/********************************************************************
|
||||
Description: ipu_mntn_rdr_init
|
||||
input: void
|
||||
output: NA
|
||||
return: int
|
||||
********************************************************************/
|
||||
int ipu_mntn_rdr_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ipu_mntn_rdr_resource_init();
|
||||
if (0 != ret) {
|
||||
printk(KERN_ERR"[%s]:IPU_ERROR:ipu_mntn_rdr_resource_init is faild!ret=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* register ics exception */
|
||||
ret = ipu_mntn_register_exception();
|
||||
if (0 != ret) {
|
||||
printk(KERN_ERR"[%s]:IPU_ERROR:ipu_mntn_register_exception is faild!ret=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* register ics dump and reset function */
|
||||
ret = ipu_mntn_register_core();
|
||||
if (0 != ret) {
|
||||
printk(KERN_ERR"[%s]:IPU_ERROR:ipu_register_core is failed!ret=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ipu_mntn_addr_map();
|
||||
if (0 != ret) {
|
||||
printk(KERN_ERR"[%s]:IPU_ERROR:ipu_mntn_addr_map is failed!ret=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#ifndef _IPU_MNTN_H_
|
||||
#define _IPU_MNTN_H_
|
||||
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/sched.h>
|
||||
#include <net/sock.h>
|
||||
#include <linux/hisi/rdr_pub.h>
|
||||
|
||||
/* AI DRD */
|
||||
#define IPU_BUF_LEN_MAX (256)
|
||||
#define IPU_LINE_MAX (128)
|
||||
|
||||
enum rdr_ipu_system_error_type {
|
||||
MODID_NPU_START = HISI_BB_MOD_NPU_START,
|
||||
MODID_NPU_EXC_DEAD = MODID_NPU_START,
|
||||
MODID_NPU_EXC_SET_BACK_CLOCK_FAIL,
|
||||
MODID_NPU_EXC_SET_CLOCK_FAIL,
|
||||
MODID_NPU_EXC_SET_POWER_UP_FAIL,
|
||||
MODID_NPU_EXC_SET_POWER_UP_STATUS_FAULT,
|
||||
MODID_NPU_EXC_SET_POWER_DOWN_FAIL,
|
||||
MODID_NPU_EXC_INTERRUPT_ABNORMAL,
|
||||
MODID_NPU_EXC_END = HISI_BB_MOD_NPU_END
|
||||
};
|
||||
|
||||
struct rdr_dump_info_s {
|
||||
u32 modid;
|
||||
u64 coreid;
|
||||
pfn_cb_dump_done cb;
|
||||
char *pathname;
|
||||
};
|
||||
|
||||
struct ipu_peri_reg_s {
|
||||
unsigned int peri_stat;
|
||||
unsigned int ppll_select;
|
||||
unsigned int power_stat;
|
||||
unsigned int power_ack;
|
||||
unsigned int reset_stat;
|
||||
unsigned int perclken0;
|
||||
unsigned int perstat0;
|
||||
};
|
||||
|
||||
struct ipu_mstr_reg_s {
|
||||
unsigned int rd_bitmap;
|
||||
unsigned int wr_bitmap;
|
||||
unsigned int rd_cmd_total_cnt0;
|
||||
unsigned int rd_cmd_total_cnt1;
|
||||
unsigned int rd_cmd_total_cnt2;
|
||||
unsigned int wr_cmd_total_cnt;
|
||||
};
|
||||
|
||||
struct ipu_mntn_info_s {
|
||||
unsigned int ipu_run_status;
|
||||
unsigned int bbox_addr_offset;
|
||||
struct rdr_register_module_result ipu_ret_info;
|
||||
struct rdr_dump_info_s dump_info;
|
||||
void *rdr_addr;
|
||||
};
|
||||
|
||||
struct ipu_reg_info_s {
|
||||
struct ipu_peri_reg_s peri_reg;
|
||||
struct ipu_mstr_reg_s mstr_reg;
|
||||
};
|
||||
|
||||
extern struct workqueue_struct *ipu_mntn_rdr_wq;
|
||||
extern struct ipu_reg_info_s ipu_reg_info;
|
||||
|
||||
extern int ipu_mntn_rdr_init(void);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,122 @@
|
||||
/* Module internals
|
||||
*
|
||||
* Copyright (C) 2016 Hisilicon, Inc. All Rights Reserved.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are the
|
||||
* copyrighted works and confidential proprietary information of
|
||||
* Hisilicon Inc. and its licensors, and are licensed to the recipient
|
||||
* under the terms of a separate license agreement. They may be
|
||||
* adapted and modified by bona fide purchasers under the terms of the
|
||||
* separate license agreement for internal use, but no adapted or
|
||||
* modified version may be disclosed or distributed to third parties
|
||||
* in any manner, medium, or form, in whole or in part, without the
|
||||
* prior written consent of Hisilicon Inc.
|
||||
*/
|
||||
|
||||
#ifndef _IPU_SMMU_DRV_H
|
||||
#define _IPU_SMMU_DRV_H
|
||||
|
||||
#include <linux/genalloc.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/hisi/hisi_ion.h>
|
||||
|
||||
#define IPU_SMMU_ENABLE
|
||||
#define CAMBRICON_IPU_IRQ
|
||||
|
||||
#define IPU_BASE_ADDRESS 0xff400000
|
||||
#define IPU_SMMU_MSTR_BASE (IPU_BASE_ADDRESS + 0xA0000)
|
||||
#define IPU_SMMU_COMM_BASE (IPU_BASE_ADDRESS + 0x80000)
|
||||
#define IPU_SMMU_MSTR_BASE_ES (IPU_BASE_ADDRESS + 0x84000)
|
||||
#define IPU_SMMU_COMM_BASE_ES (IPU_BASE_ADDRESS + 0x80000)
|
||||
#define IPU_SMMU_READ_STREAM_NUMBER (3)
|
||||
#define IPU_SMMU_TAG_COMPARE_CASE_NUMBER (6)
|
||||
#define IPU_SMMU_TOTAL_STREAM_ID_NUMBER (4)
|
||||
|
||||
#ifdef CONFIG_HUAWEI_DSM
|
||||
#define REGISTER_INFO_MAX_LEN (1024)
|
||||
extern char register_info[REGISTER_INFO_MAX_LEN];
|
||||
#endif
|
||||
|
||||
#define DEBUG(fmt, ...) printk(KERN_DEBUG "[%s+%d]: " fmt "\n", __func__, __LINE__, ##__VA_ARGS__)
|
||||
|
||||
struct map_format {
|
||||
unsigned long iova_start;
|
||||
unsigned long iova_size;
|
||||
int prot;
|
||||
};
|
||||
|
||||
struct map_data {
|
||||
int share_fd;
|
||||
struct map_format format;
|
||||
};
|
||||
|
||||
struct memory_manage_node {
|
||||
struct list_head head;
|
||||
struct map_data map;
|
||||
};
|
||||
|
||||
struct smmu_irq_count {
|
||||
unsigned int mstr_wdata_burst;
|
||||
unsigned int mstr_wr_va_out_of_128byte;
|
||||
unsigned int mstr_wr_va_out_of_boundary;
|
||||
unsigned int mstr_rd_va_out_of_128byte;
|
||||
unsigned int mstr_rd_va_out_of_boundary;
|
||||
unsigned int comm_ptw_ns_stat;
|
||||
unsigned int comm_ptw_invalid_stat;
|
||||
unsigned int comm_ptw_trans_stat;
|
||||
unsigned int comm_tlbmiss_stat;
|
||||
unsigned int comm_ext_stat;
|
||||
unsigned int comm_permis_stat;
|
||||
};
|
||||
|
||||
struct smmu_statistic {
|
||||
unsigned int read_stream_cmd_total[IPU_SMMU_READ_STREAM_NUMBER];
|
||||
unsigned int read_stream_cmd_miss[IPU_SMMU_READ_STREAM_NUMBER];
|
||||
unsigned int read_stream_data_total[IPU_SMMU_READ_STREAM_NUMBER];
|
||||
unsigned int read_stream_cmd_miss_valid;
|
||||
unsigned int read_stream_cmd_miss_pending;
|
||||
unsigned int read_stream_cmd_hit_valid_not_slide_window;
|
||||
unsigned int read_stream_cmd_hit_valid_slide_window;
|
||||
unsigned int read_stream_cmd_hit_pending_not_slide_window;
|
||||
unsigned int read_stream_cmd_hit_pending_slide_window;
|
||||
unsigned int read_stream_cmd_latency;
|
||||
unsigned int write_stream_cmd_total;
|
||||
unsigned int write_stream_cmd_miss;
|
||||
unsigned int write_stream_data_total;
|
||||
unsigned int write_stream_cmd_miss_valid;
|
||||
unsigned int write_stream_cmd_miss_pending;
|
||||
unsigned int write_stream_cmd_hit_valid_not_slide_window;
|
||||
unsigned int write_stream_cmd_hit_valid_slide_window;
|
||||
unsigned int write_stream_cmd_hit_pending_not_slide_window;
|
||||
unsigned int write_stream_cmd_hit_pending_slide_window;
|
||||
unsigned int write_stream_cmd_latency;
|
||||
struct smmu_irq_count smmu_irq_count;
|
||||
};
|
||||
|
||||
extern struct ion_client* ipu_ion_client;
|
||||
|
||||
extern void ipu_smmu_init(unsigned long ttbr0, unsigned long smmu_rw_err_phy_addr, bool port_sel, bool hardware_start);
|
||||
extern void ipu_smmu_deinit(void);
|
||||
extern unsigned long ipu_get_smmu_base_phy(struct device *dev);
|
||||
extern long ipu_smmu_map(struct map_data *map);
|
||||
extern long ipu_smmu_unmap(struct map_data *map);
|
||||
extern bool ipu_smmu_interrupt_handler(struct smmu_irq_count *irq_count);
|
||||
extern void ipu_smmu_reset_statistic(void);
|
||||
extern void ipu_smmu_record_statistic(struct smmu_statistic *statistic);
|
||||
extern void ipu_smmu_pte_update(void);
|
||||
extern bool ipu_smmu_master_get_offset(struct device *dev);
|
||||
extern bool ipu_smmu_common_get_offset(struct device *dev);
|
||||
extern void ipu_smmu_override_prefetch_addr(unsigned long reset_va);
|
||||
extern int ipu_smmu_mngr_init(void);
|
||||
extern void ipu_smmu_mngr_deinit(void);
|
||||
extern void ipu_mem_mngr_init(void);
|
||||
extern void ipu_mem_mngr_deinit(unsigned long *reset_va);
|
||||
extern void * ipu_mem_mngr_add(struct map_data *map);
|
||||
extern int ipu_mem_mngr_del(struct map_data *map);
|
||||
extern int ipu_mem_mngr_check_valid(unsigned int inst_addr);
|
||||
extern void ipu_mem_mngr_dump(void);
|
||||
extern void ipu_smmu_dump_strm(void);
|
||||
|
||||
#endif
|
||||
@@ -353,6 +353,6 @@
|
||||
/*clk media2*/
|
||||
#define KIRIN970_CLK_GATE_VDECFREQ 0
|
||||
#define KIRIN970_CLK_GATE_VENCFREQ 1
|
||||
|
||||
#define KIRIN970_CLK_GATE_ICSFREQ 2
|
||||
|
||||
#endif /* __DT_BINDINGS_CLOCK_KIRIN970_H */
|
||||
|
||||
Reference in New Issue
Block a user