mirror of
https://github.com/revyos/thead-kernel.git
synced 2026-06-21 09:12:26 +02:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9cf70c75d | ||
|
|
f6b3a51dab | ||
|
|
2a1c09c089 | ||
|
|
745c35085c | ||
|
|
39a7c4f518 | ||
|
|
99a0ff503d | ||
|
|
483521ff86 | ||
|
|
9ffddd4172 | ||
|
|
a8a3aef9b9 | ||
|
|
3bff12eab2 | ||
|
|
8e7282e217 | ||
|
|
d2247b2403 | ||
|
|
3ef68d010b | ||
|
|
930b7d92fd | ||
|
|
9ee78c8b51 | ||
|
|
719387f851 | ||
|
|
93090f65c3 | ||
|
|
32bd505b1d | ||
|
|
e3d0728cb3 | ||
|
|
9cc3fa38f8 |
@@ -326,6 +326,14 @@ config SMP
|
||||
|
||||
If you don't know what to do here, say N.
|
||||
|
||||
config SCHED_MC
|
||||
bool "Multi-core scheduler support"
|
||||
depends on SMP
|
||||
help
|
||||
Multi-core scheduler support improves the CPU scheduler's decision
|
||||
making when dealing with multi-core CPU chips at a cost of slightly
|
||||
increased overhead in some places. If unsure say N here.
|
||||
|
||||
config NR_CPUS
|
||||
int "Maximum number of CPUs (2-32)"
|
||||
range 2 32
|
||||
|
||||
@@ -56,10 +56,12 @@ dtb-$(CONFIG_SOC_THEAD_FIRE) += fire-emu-soc-base-sec.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += th1520-beagle.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += th1520-lpi4a-16gb.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += th1520-lpi4a-laptop.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += th1520-lpi4a-pocket.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += th1520-lpi4a-console.dtb th1520-lpi4a-console-16g.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += th1520-lpi4a-plastic.dtb th1520-lpi4a-plastic-16g.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += th1520-lpi4a-cluster.dtb th1520-lpi4a-cluster-16gb.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += th1520-lpi4a-z14inch-m0.dtb th1520-lpi4a-z14inch-m0-16g.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += th1520-milkv-meles.dtb th1520-milkv-meles-4g.dtb th1520-milkv-meles-dsi0.dtb
|
||||
dtb-$(CONFIG_SOC_THEAD) += th1520-milkv-meles.dtb th1520-milkv-meles-4g.dtb th1520-milkv-meles-16g.dtb th1520-milkv-meles-dsi0.dtb
|
||||
|
||||
# compat old name
|
||||
dtb-$(CONFIG_SOC_THEAD) += light-lpi4a.dtb light-lpi4a-16gb.dtb
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
};
|
||||
|
||||
&i2c3 {
|
||||
touch@14 {
|
||||
goodix_tp: touch@14 {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "goodix,gt9271";
|
||||
reg = <0x14>;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
};
|
||||
|
||||
&i2c3 {
|
||||
touch@14 {
|
||||
goodix_tp: touch@14 {
|
||||
touchscreen-size-x = <800>;
|
||||
touchscreen-size-y = <1200>;
|
||||
status = "okay";
|
||||
|
||||
@@ -76,9 +76,17 @@
|
||||
vin-supply = <®_sys_vcc_5v>;
|
||||
gpio = <&pcal6408ahk_c 1 1>;
|
||||
enable-active-high;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
sata_pwr_switch: sata-pwr-switch {
|
||||
status = "okay";
|
||||
compatible = "reg-userspace-consumer";
|
||||
regulator-name = "sata-pwr-consumer";
|
||||
vcc-supply = <®_sata_vcc_5v>;
|
||||
};
|
||||
|
||||
audio_amp: regulator-audio-amp-en {
|
||||
status = "okay";
|
||||
compatible = "regulator-fixed";
|
||||
@@ -137,14 +145,12 @@
|
||||
};
|
||||
|
||||
&wcn_wifi {
|
||||
// WIFI,poweren_gpio = <&pcal6408ahk_c 4 0>;
|
||||
/delete-property/ WIFI,poweren_gpio;
|
||||
WIFI,poweren_gpio = <&pcal6408ahk_c 4 0>;
|
||||
};
|
||||
|
||||
|
||||
&wcn_bt {
|
||||
// BT,power_gpio = <&pcal6408ahk_c 5 0>;
|
||||
/delete-property/ BT,power_gpio;
|
||||
BT,power_gpio = <&pcal6408ahk_c 5 0>;
|
||||
};
|
||||
|
||||
&usb_1 {
|
||||
|
||||
17
arch/riscv/boot/dts/thead/th1520-lpi4a-plastic-16g.dts
Normal file
17
arch/riscv/boot/dts/thead/th1520-lpi4a-plastic-16g.dts
Normal file
@@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 Alibaba Group Holding Limited.
|
||||
*/
|
||||
|
||||
#include "th1520-lpi4a-plastic.dts"
|
||||
|
||||
/ {
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x200000 0x3 0xffe00000>;
|
||||
};
|
||||
};
|
||||
|
||||
&cmamem {
|
||||
alloc-ranges = <0x3 0xe4000000 0 0x14000000>; // [0x3E400_0000 ~ 0x3F800_0000]
|
||||
};
|
||||
78
arch/riscv/boot/dts/thead/th1520-lpi4a-plastic.dts
Normal file
78
arch/riscv/boot/dts/thead/th1520-lpi4a-plastic.dts
Normal file
@@ -0,0 +1,78 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2024 Sipeed.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include "th1520-lpi4a-laptop.dts"
|
||||
|
||||
/ {
|
||||
model = "T-HEAD Light Lichee Pi 4A configuration for Plastic laptop";
|
||||
};
|
||||
|
||||
&dsi0_panel0 {
|
||||
compatible = "cmn,5171_1920x1200_40Hz";
|
||||
};
|
||||
|
||||
&i2c2 {
|
||||
touchpad: touchpad@2c {
|
||||
compatible = "hid-over-i2c";
|
||||
reg = <0x2c>;
|
||||
hid-descr-addr = <0x0020>;
|
||||
interrupt-parent = <&gpio1_porta>;
|
||||
interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
&cw2015 {
|
||||
cellwise,battery-profile = /bits/ 8 <
|
||||
0x17 0x67 0x72 0x68 0x66 0x63 0x62 0x5A
|
||||
0x64 0x61 0x4D 0x57 0x5A 0x51 0x43 0x38
|
||||
0x31 0x2A 0x24 0x22 0x29 0x31 0x3E 0x4C
|
||||
0x29 0x4D 0x0B 0x85 0x1C 0x38 0x47 0x57
|
||||
0x5D 0x5E 0x5F 0x60 0x3F 0x1A 0x6F 0x41
|
||||
0x0A 0x43 0x12 0x38 0x7B 0x95 0x9A 0x18
|
||||
0x4B 0x6F 0x9E 0xD5 0x80 0x57 0x87 0xCB
|
||||
0x2F 0x00 0x64 0xA5 0xB5 0x13 0x54 0xB9
|
||||
>;
|
||||
};
|
||||
|
||||
<8911 {
|
||||
// CMN5171
|
||||
lontium,pclk = <160000000>; // 60Hz
|
||||
lontium,hact = <1920>;
|
||||
lontium,vact = <1200>;
|
||||
lontium,hbp = <105>;
|
||||
lontium,hfp = <58>;
|
||||
lontium,vbp = <20>;
|
||||
lontium,vfp = <10>;
|
||||
lontium,hs = <37>;
|
||||
lontium,vs = <6>;
|
||||
lontium,mipi_lane = <2>;
|
||||
lontium,lane_cnt = <2>;
|
||||
lontium,color = <1>; //Color Depth 0:6bit 1:8bit
|
||||
lontium,test = <0>;
|
||||
};
|
||||
|
||||
&fan_config0 {
|
||||
temperature = <40000>;
|
||||
};
|
||||
|
||||
&fan_config1 {
|
||||
temperature = <60000>;
|
||||
};
|
||||
|
||||
&fan_config2 {
|
||||
temperature = <80000>;
|
||||
};
|
||||
|
||||
&fan {
|
||||
pwms = <&pwm 1 100000 0>;
|
||||
cooling-levels = <0x10 0x30 0x50 0xFF>;
|
||||
};
|
||||
|
||||
&lcd0_backlight {
|
||||
//pwms = <&pwm 0 50000>;
|
||||
pwms = <&pwm 0 1000000>;
|
||||
default-brightness-level = <40>;
|
||||
};
|
||||
219
arch/riscv/boot/dts/thead/th1520-lpi4a-pocket.dts
Normal file
219
arch/riscv/boot/dts/thead/th1520-lpi4a-pocket.dts
Normal file
@@ -0,0 +1,219 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2023 Sipeed.
|
||||
*/
|
||||
|
||||
#include "th1520-lpi4a-dsi0-hdmi.dts"
|
||||
|
||||
/ {
|
||||
model = "LicheePocket4A 8G";
|
||||
compatible = "thead,light", "sipeed,pocket4a";
|
||||
|
||||
charger: dc-charger {
|
||||
compatible = "gpio-charger";
|
||||
charger-type = "mains";
|
||||
gpios = <&gpio1_porta 3 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
&uart1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&uart3 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&lcd0_backlight {
|
||||
pwms = <&pwm 0 10000>; // 100Khz
|
||||
brightness-levels = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
||||
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
||||
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100>;
|
||||
default-brightness-level = <30>;
|
||||
};
|
||||
|
||||
&fan {
|
||||
pwms = <&pwm 1 10000000 0>;
|
||||
//cooling-levels = <0 64 192 255>;
|
||||
cooling-levels = <192 192 192 255>;
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
/delete-node/ gpio@18;
|
||||
|
||||
cw2015: cw2015@62 {
|
||||
compatible = "cellwise,cw2015";
|
||||
status = "disabled";
|
||||
reg = <0x62>;
|
||||
cellwise,monitor-interval-ms = <5000>;
|
||||
power-supplies = <&charger>;
|
||||
cellwise,battery-profile = /bits/ 8 <
|
||||
0x17 0x67 0x80 0x73 0x6E 0x6C 0x6B 0x63
|
||||
0x77 0x51 0x5C 0x58 0x50 0x4C 0x48 0x36
|
||||
0x15 0x0C 0x0C 0x19 0x5B 0x7D 0x6F 0x69
|
||||
0x69 0x5B 0x0C 0x29 0x20 0x40 0x52 0x59
|
||||
0x57 0x56 0x54 0x4F 0x3B 0x1F 0x7F 0x17
|
||||
0x06 0x1A 0x30 0x5A 0x85 0x93 0x96 0x2D
|
||||
0x48 0x77 0x9C 0xB3 0x80 0x52 0x94 0xCB
|
||||
0x2F 0x00 0x64 0xA5 0xB5 0x11 0xF0 0x11
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
&i2c3 {
|
||||
/delete-node/ gpio@18;
|
||||
};
|
||||
|
||||
&goodix_tp {
|
||||
#gpio-cells = <2>;
|
||||
compatible = "goodix,gt9271";
|
||||
reg = <0x14>;
|
||||
interrupt-parent = <&ao_gpio_porta>;
|
||||
interrupts = <3 0>;
|
||||
irq-gpios = <&ao_gpio_porta 3 0>;
|
||||
reset-gpios = <&pcal6408ahk_c 0 0>;
|
||||
touchscreen-size-x = <800>;
|
||||
touchscreen-size-y = <1280>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
®_tp_pwr_en {
|
||||
/delete-property/ gpio;
|
||||
};
|
||||
|
||||
®_usb_hub_vdd1v2 {
|
||||
/delete-property/ gpio;
|
||||
};
|
||||
|
||||
&vvcam_sensor1 {
|
||||
sensor_pdn = <&gpio1_porta 30 0>;
|
||||
sensor_rst = <&pcal6408ahk_c 2 0>;
|
||||
i2c_bus = /bits/ 8 <0>;
|
||||
};
|
||||
|
||||
&key_volup {
|
||||
gpios = <&gpio2_porta 16 0x1>;
|
||||
};
|
||||
|
||||
®_usb_hub_vcc5v {
|
||||
/delete-property/ gpio;
|
||||
};
|
||||
|
||||
&soc_vdd33_lcd0_en_reg {
|
||||
/delete-property/ gpio;
|
||||
};
|
||||
|
||||
&soc_vdd18_lcd0_en_reg {
|
||||
/delete-property/ gpio;
|
||||
};
|
||||
|
||||
&soc_avdd28_rgb_reg {
|
||||
/delete-property/ gpio;
|
||||
};
|
||||
|
||||
&soc_dovdd18_rgb_reg {
|
||||
/delete-property/ gpio;
|
||||
};
|
||||
|
||||
&soc_dvdd12_rgb_reg {
|
||||
/delete-property/ gpio;
|
||||
};
|
||||
|
||||
&soc_avdd25_ir_reg {
|
||||
/delete-property/ gpio;
|
||||
};
|
||||
|
||||
&soc_dovdd18_ir_reg {
|
||||
/delete-property/ gpio;
|
||||
};
|
||||
|
||||
&soc_dvdd12_ir_reg {
|
||||
/delete-property/ gpio;
|
||||
};
|
||||
|
||||
&soc_cam2_avdd25_ir_reg {
|
||||
/delete-property/ gpio;
|
||||
};
|
||||
|
||||
&soc_cam2_dovdd18_ir_reg {
|
||||
/delete-property/ gpio;
|
||||
};
|
||||
|
||||
&soc_cam2_dvdd12_ir_reg {
|
||||
/delete-property/ gpio;
|
||||
};
|
||||
|
||||
&dsi0_panel0 {
|
||||
compatible = "chongzhou,cz101b4001", "jadard,jd9365da-h3";
|
||||
backlight = <&lcd0_backlight>;
|
||||
reset-gpio = <&pcal6408ahk_c 3 0>; /* active low */
|
||||
/delete-property/ hsvcc-supply;
|
||||
/delete-property/ vspn3v3-supply;
|
||||
};
|
||||
|
||||
&usb_1 {
|
||||
/delete-property/ hubswitch-gpio;
|
||||
/delete-property/ hub1v2-supply;
|
||||
/delete-property/ hub5v-supply;
|
||||
};
|
||||
|
||||
&cpus {
|
||||
c910_0: cpu@0 {
|
||||
operating-points = <
|
||||
/* kHz uV */
|
||||
300000 500000
|
||||
800000 700000
|
||||
1500000 800000
|
||||
>;
|
||||
light,dvddm-operating-points = <
|
||||
/* kHz uV */
|
||||
300000 800000
|
||||
800000 800000
|
||||
1500000 800000
|
||||
>;
|
||||
};
|
||||
c910_1: cpu@1 {
|
||||
operating-points = <
|
||||
/* kHz uV */
|
||||
300000 500000
|
||||
800000 700000
|
||||
1500000 800000
|
||||
>;
|
||||
light,dvddm-operating-points = <
|
||||
/* kHz uV */
|
||||
300000 800000
|
||||
800000 800000
|
||||
1500000 800000
|
||||
>;
|
||||
};
|
||||
c910_2: cpu@2 {
|
||||
|
||||
operating-points = <
|
||||
/* kHz uV */
|
||||
300000 500000
|
||||
800000 700000
|
||||
1500000 800000
|
||||
>;
|
||||
light,dvddm-operating-points = <
|
||||
/* kHz uV */
|
||||
300000 800000
|
||||
800000 800000
|
||||
1500000 800000
|
||||
>;
|
||||
};
|
||||
c910_3: cpu@3 {
|
||||
|
||||
operating-points = <
|
||||
/* kHz uV */
|
||||
300000 500000
|
||||
800000 700000
|
||||
1500000 800000
|
||||
>;
|
||||
light,dvddm-operating-points = <
|
||||
/* kHz uV */
|
||||
300000 800000
|
||||
800000 800000
|
||||
1500000 800000
|
||||
>;
|
||||
};
|
||||
};
|
||||
@@ -273,7 +273,8 @@
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_wifi_wake>;
|
||||
wifi_chip_type = "rtl8723ds";
|
||||
// WIFI,poweren_gpio = <&pcal6408ahk_c 4 0>;
|
||||
WIFI,poweren_gpio = <&pcal6408ahk_c 4 0>;
|
||||
support_power_ctrl;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -281,7 +282,7 @@
|
||||
compatible = "bluetooth-platdata";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_bt_wake>;
|
||||
// BT,power_gpio = <&pcal6408ahk_c 5 0>;
|
||||
BT,power_gpio = <&pcal6408ahk_c 5 0>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -295,7 +296,7 @@
|
||||
debounce-interval = <1>;
|
||||
gpios = <&gpio1_porta 19 0x1>;
|
||||
};
|
||||
key-volumeup {
|
||||
key_volup: key-volumeup {
|
||||
label = "Volume Up Key";
|
||||
linux,code = <KEY_VOLUMEUP>;
|
||||
debounce-interval = <1>;
|
||||
@@ -992,12 +993,13 @@
|
||||
pull_up;
|
||||
no-sd;
|
||||
no-mmc;
|
||||
non-removable;
|
||||
broken-cd;
|
||||
io_fixed_1v8;
|
||||
post-power-on-delay-ms = <50>;
|
||||
wprtn_ignore;
|
||||
cap-sd-highspeed;
|
||||
wakeup-source;
|
||||
keep-power-in-suspend;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -1174,7 +1176,6 @@
|
||||
>;
|
||||
};
|
||||
|
||||
|
||||
pinctrl_uart3_tx_is_gpio: uart3txisgpiogrp {
|
||||
thead,pins = <
|
||||
FM_UART3_TXD 0x3 0x202
|
||||
@@ -1184,6 +1185,7 @@
|
||||
|
||||
|
||||
|
||||
|
||||
pinctrl_wifi_wake: wifi_grp {
|
||||
thead,pins = <
|
||||
FM_GPIO0_27 0x0 0x202
|
||||
@@ -1525,6 +1527,13 @@
|
||||
channel0 {
|
||||
channel_id = <0>;
|
||||
status = "okay";
|
||||
sensor0 {
|
||||
subdev_name = "vivcam";
|
||||
idx = <0>;
|
||||
csi_idx = <0>;
|
||||
mode_idx = <0>;
|
||||
path_type = "SENSOR_VGA_RAW12_LINER";
|
||||
};
|
||||
sensor1 {
|
||||
subdev_name = "vivcam";
|
||||
idx = <3>;
|
||||
@@ -1550,6 +1559,13 @@
|
||||
};
|
||||
};
|
||||
channel1 {
|
||||
sensor0 {
|
||||
subdev_name = "vivcam";
|
||||
idx = <0>;
|
||||
csi_idx = <0>;
|
||||
mode_idx = <0>;
|
||||
path_type = "SENSOR_VGA_RAW12_LINER";
|
||||
};
|
||||
sensor1 {
|
||||
subdev_name = "vivcam";
|
||||
idx = <3>;
|
||||
@@ -1570,6 +1586,13 @@
|
||||
};
|
||||
};
|
||||
channel2 {
|
||||
sensor0 {
|
||||
subdev_name = "vivcam";
|
||||
idx = <0>;
|
||||
csi_idx = <0>;
|
||||
mode_idx = <0>;
|
||||
path_type = "SENSOR_VGA_RAW12_LINER";
|
||||
};
|
||||
sensor1 {
|
||||
subdev_name = "vivcam";
|
||||
idx = <3>;
|
||||
@@ -1595,6 +1618,14 @@
|
||||
vi_mem_pool_region = <0>; // vi_mem: framebuffer, region[0]
|
||||
status = "okay";
|
||||
channel0 {
|
||||
sensor0 {
|
||||
subdev_name = "vivcam";
|
||||
idx = <0>;
|
||||
csi_idx = <0>;
|
||||
mode_idx = <0>;
|
||||
path_type = "SENSOR_VGA_RAW12_LINER";
|
||||
|
||||
};
|
||||
sensor1 {
|
||||
subdev_name = "vivcam";
|
||||
idx = <3>;
|
||||
|
||||
17
arch/riscv/boot/dts/thead/th1520-milkv-meles-16g.dts
Normal file
17
arch/riscv/boot/dts/thead/th1520-milkv-meles-16g.dts
Normal file
@@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 Alibaba Group Holding Limited.
|
||||
*/
|
||||
|
||||
#include "th1520-milkv-meles.dts"
|
||||
|
||||
/ {
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x200000 0x3 0xffe00000>;
|
||||
};
|
||||
};
|
||||
|
||||
&cmamem {
|
||||
alloc-ranges = <0x3 0xe4000000 0 0x14000000>; // [0x3E400_0000 ~ 0x3F800_0000]
|
||||
};
|
||||
@@ -848,12 +848,11 @@
|
||||
|
||||
pinctrl_hdmi: hdmigrp {
|
||||
thead,pins = <
|
||||
FM_HDMI_SCL 0x0 0x202
|
||||
FM_HDMI_SDA 0x0 0x202
|
||||
FM_HDMI_CEC 0x0 0x202
|
||||
FM_HDMI_SCL 0x0 0x208
|
||||
FM_HDMI_SDA 0x0 0x208
|
||||
FM_HDMI_CEC 0x0 0x208
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_gmac0: gmac0grp {
|
||||
thead,pins = <
|
||||
FM_GMAC0_TX_CLK 0x0 0x20f /* GMAC0_TX_CLK */
|
||||
|
||||
@@ -10,6 +10,7 @@ CONFIG_NAMESPACES=y
|
||||
CONFIG_USER_NS=y
|
||||
CONFIG_CHECKPOINT_RESTORE=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_SCHED_MC=y
|
||||
CONFIG_EXPERT=y
|
||||
# CONFIG_BUG is not set
|
||||
CONFIG_BPF_SYSCALL=y
|
||||
|
||||
@@ -29,6 +29,7 @@ CONFIG_NAMESPACES=y
|
||||
CONFIG_USER_NS=y
|
||||
CONFIG_CHECKPOINT_RESTORE=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
CONFIG_SCHED_MC=y
|
||||
CONFIG_EXPERT=y
|
||||
# CONFIG_BUG is not set
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
@@ -70,6 +71,7 @@ CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM_USER=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_SET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
CONFIG_IP_PNP=y
|
||||
@@ -78,6 +80,7 @@ CONFIG_IP_PNP_BOOTP=y
|
||||
CONFIG_IP_PNP_RARP=y
|
||||
CONFIG_NET_IPVTI=y
|
||||
CONFIG_INET_ESP=y
|
||||
CONFIG_INET_XFRM_MODE_TRANSPORT=y
|
||||
CONFIG_TCP_CONG_ADVANCED=y
|
||||
CONFIG_TCP_CONG_BBR=m
|
||||
CONFIG_NETFILTER=y
|
||||
@@ -92,9 +95,11 @@ CONFIG_NETFILTER_XT_NAT=y
|
||||
CONFIG_NETFILTER_XT_TARGET_REDIRECT=y
|
||||
CONFIG_NETFILTER_XT_TARGET_MASQUERADE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_IPVS=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MARK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
|
||||
CONFIG_IP_VS=y
|
||||
CONFIG_IP_VS_PROTO_TCP=y
|
||||
CONFIG_IP_VS_PROTO_UDP=y
|
||||
@@ -239,6 +244,10 @@ CONFIG_LIGHT_PMIC_WATCHDOG=y
|
||||
CONFIG_ABX500_CORE=y
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||
CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
|
||||
CONFIG_REGULATOR_USERSPACE_CONSUMER=y
|
||||
CONFIG_REGULATOR_GPIO=y
|
||||
CONFIG_REGULATOR_PWM=y
|
||||
CONFIG_MEDIA_SUPPORT=y
|
||||
# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
|
||||
# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
|
||||
@@ -293,7 +302,7 @@ CONFIG_DRM_PANEL_HX8394=y
|
||||
CONFIG_DRM_PANEL_JADARD_JD9365DA_H3=y
|
||||
CONFIG_DRM_PANEL_MINGJUN_070BI30IA2=y
|
||||
CONFIG_DRM_PANEL_HX8279=y
|
||||
CONFIG_DRM_LONTIUM_LT8911EXB=m
|
||||
CONFIG_DRM_LONTIUM_LT8911EXB=y
|
||||
CONFIG_DRM_ETNAVIV=m
|
||||
CONFIG_DRM_VERISILICON=y
|
||||
CONFIG_DRM_POWERVR_ROGUE=m
|
||||
@@ -314,8 +323,10 @@ CONFIG_SND_SOC_ES8156=y
|
||||
CONFIG_SND_SOC_WM8960=y
|
||||
CONFIG_SND_SIMPLE_CARD=y
|
||||
CONFIG_SND_AUDIO_GRAPH_CARD=y
|
||||
CONFIG_HIDRAW=m
|
||||
CONFIG_UHID=y
|
||||
CONFIG_HID_PID=y
|
||||
CONFIG_HID_MULTITOUCH=m
|
||||
CONFIG_USB_HIDDEV=y
|
||||
CONFIG_I2C_HID=m
|
||||
CONFIG_USB=y
|
||||
|
||||
@@ -98,7 +98,7 @@ void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
||||
"sfence.vma t0, t0\n\t"
|
||||
::: "memory", "t0");
|
||||
|
||||
csr_write(sptbr, virt_to_pfn(next->pgd) | SATP_MODE | asid);
|
||||
csr_write(satp, virt_to_pfn(next->pgd) | SATP_MODE | asid);
|
||||
#endif
|
||||
|
||||
flush_icache_deferred(next);
|
||||
|
||||
@@ -4570,6 +4570,37 @@ static const struct panel_desc_dsi z14inch_2160x1440_40Hz = {
|
||||
};
|
||||
|
||||
|
||||
/* TODO: move timing into device tree */
|
||||
static const struct drm_display_mode cmn_5171_1920x1200_40Hz_mode = {
|
||||
.clock = 127750,
|
||||
.hdisplay = 1920,
|
||||
.hsync_start = 1920 + 46, /* hact + hfp */
|
||||
.hsync_end = 1920 + 46 + 30, /* hact + hfp + hs */
|
||||
.htotal = 1920 + 46 + 30 + 84, /* hact + hfp + hs + hbp */
|
||||
.vdisplay = 1200,
|
||||
.vsync_start = 1200 + 10, /* vact + vfp */
|
||||
.vsync_end = 1200 + 10 + 6, /* vact + vfp + vs */
|
||||
.vtotal = 1200 + 10 + 6 + 20, /* vact + vfp + vs + vbp */
|
||||
.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
|
||||
};
|
||||
|
||||
static const struct panel_desc_dsi cmn_5171_1920x1200_40Hz = {
|
||||
.desc = {
|
||||
.modes = &cmn_5171_1920x1200_40Hz_mode,
|
||||
.num_modes = 1,
|
||||
.bpc = 8,
|
||||
.size = {
|
||||
.width = 62,
|
||||
.height = 110,
|
||||
},
|
||||
.connector_type = DRM_MODE_CONNECTOR_DSI,
|
||||
},
|
||||
.flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_VIDEO_BURST,
|
||||
.format = MIPI_DSI_FMT_RGB888,
|
||||
.lanes = 4,
|
||||
};
|
||||
|
||||
|
||||
static const struct drm_display_mode lg_ld070wx3_sl01_mode = {
|
||||
.clock = 71000,
|
||||
.hdisplay = 800,
|
||||
@@ -4771,6 +4802,9 @@ static const struct of_device_id dsi_of_match[] = {
|
||||
}, {
|
||||
.compatible = "custom,z14inch_2160x1440_40Hz",
|
||||
.data = &z14inch_2160x1440_40Hz
|
||||
}, {
|
||||
.compatible = "cmn,5171_1920x1200_40Hz",
|
||||
.data = &cmn_5171_1920x1200_40Hz
|
||||
}, {
|
||||
/* sentinel */
|
||||
}
|
||||
|
||||
@@ -126,8 +126,9 @@
|
||||
* status codes
|
||||
*/
|
||||
#define STATUS_IDLE 0x0
|
||||
#define STATUS_WRITE_IN_PROGRESS 0x1
|
||||
#define STATUS_READ_IN_PROGRESS 0x2
|
||||
#define STATUS_ACTIVE 0x1
|
||||
#define STATUS_WRITE_IN_PROGRESS 0x2
|
||||
#define STATUS_READ_IN_PROGRESS 0x4
|
||||
|
||||
/*
|
||||
* operation modes
|
||||
@@ -331,12 +332,14 @@ void i2c_dw_disable_int(struct dw_i2c_dev *dev);
|
||||
|
||||
static inline void __i2c_dw_enable(struct dw_i2c_dev *dev)
|
||||
{
|
||||
dev->status |= STATUS_ACTIVE;
|
||||
regmap_write(dev->map, DW_IC_ENABLE, 1);
|
||||
}
|
||||
|
||||
static inline void __i2c_dw_disable_nowait(struct dw_i2c_dev *dev)
|
||||
{
|
||||
regmap_write(dev->map, DW_IC_ENABLE, 0);
|
||||
dev->status &= ~STATUS_ACTIVE;
|
||||
}
|
||||
|
||||
void __i2c_dw_disable(struct dw_i2c_dev *dev);
|
||||
|
||||
@@ -261,9 +261,9 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
|
||||
|
||||
if (dev->dw_i2c_enable_dma) {
|
||||
i2c_dw_xfer_dma_init(dev);
|
||||
regmap_write(dev->map, DW_IC_INTR_MASK, DW_IC_INTR_MASTER_MASK & (~DW_IC_INTR_TX_EMPTY));
|
||||
regmap_write(dev->map, DW_IC_INTR_MASK, (DW_IC_INTR_MASTER_MASK & (~DW_IC_INTR_TX_EMPTY))|DW_IC_INTR_RX_OVER);
|
||||
} else {
|
||||
regmap_write(dev->map, DW_IC_INTR_MASK, DW_IC_INTR_MASTER_MASK);
|
||||
regmap_write(dev->map, DW_IC_INTR_MASK, DW_IC_INTR_MASTER_MASK|DW_IC_INTR_RX_OVER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,7 +433,6 @@ i2c_dw_read(struct dw_i2c_dev *dev)
|
||||
}
|
||||
|
||||
regmap_read(dev->map, DW_IC_RXFLR, &rx_valid);
|
||||
|
||||
for (; len > 0 && rx_valid > 0; len--, rx_valid--) {
|
||||
u32 flags = msgs[dev->msg_read_idx].flags;
|
||||
|
||||
@@ -546,12 +545,14 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
|
||||
}
|
||||
|
||||
if (dev->status || dev->tx_status) {
|
||||
dev_err(dev->dev, "transfer terminated early - interrupt latency too high? sta 0x%x\n", dev->status);
|
||||
|
||||
dev_err(dev->dev, "laststa 0x%x, laststatus 0x%x\n", dev->laststat, dev->laststatus);
|
||||
dev_err(dev->dev, "dev->tx_status 0x%x\n", dev->tx_status);
|
||||
dev_err(dev->dev, "dev->rx_outstanding %d\n", dev->rx_outstanding);
|
||||
}
|
||||
dev_err(dev->dev, "transfer terminated early - interrupt latency too high? sta 0x%x,tx_status 0x%x\n",dev->status,dev->tx_status);
|
||||
dev_err(dev->dev, "laststa 0x%x, laststatus 0x%x,rx_outstanding %d\n", dev->laststat, dev->laststatus, dev->rx_outstanding);
|
||||
if(dev->laststat&DW_IC_INTR_RX_OVER)
|
||||
{
|
||||
ret = -EAGAIN;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
ret = -EIO;
|
||||
|
||||
@@ -640,6 +641,19 @@ static int i2c_dw_irq_handler_master(struct dw_i2c_dev *dev)
|
||||
u32 stat, status;
|
||||
|
||||
stat = i2c_dw_read_clear_intrbits(dev);
|
||||
|
||||
if(!(dev->status & STATUS_ACTIVE)) {
|
||||
/*
|
||||
* Unexpected interrupt in driver point of view. State
|
||||
* variables are either unset or stale so acknowledge and
|
||||
* disable interrupts for suppressing further interrupts if
|
||||
* interrupt really came from this HW (E.g. firmware has left
|
||||
* the HW active).
|
||||
*/
|
||||
regmap_write(dev->map, DW_IC_INTR_MASK, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (stat & DW_IC_INTR_TX_ABRT) {
|
||||
dev->cmd_err |= DW_IC_ERR_TX_ABRT;
|
||||
dev->status = STATUS_IDLE;
|
||||
@@ -653,8 +667,13 @@ static int i2c_dw_irq_handler_master(struct dw_i2c_dev *dev)
|
||||
}
|
||||
goto tx_aborted;
|
||||
}
|
||||
|
||||
if (stat & DW_IC_INTR_RX_FULL)
|
||||
if(stat & DW_IC_INTR_RX_OVER)
|
||||
{
|
||||
/* Anytime RX_OVER is set, Make sure to skip them.*/
|
||||
regmap_write(dev->map, DW_IC_INTR_MASK, 0);
|
||||
goto tx_aborted;
|
||||
}
|
||||
if ((stat & DW_IC_INTR_RX_FULL) || (dev->rx_outstanding >0))
|
||||
i2c_dw_read(dev);
|
||||
|
||||
if (stat & DW_IC_INTR_TX_EMPTY) {
|
||||
@@ -669,13 +688,14 @@ static int i2c_dw_irq_handler_master(struct dw_i2c_dev *dev)
|
||||
|
||||
tx_aborted:
|
||||
regmap_read(dev->map, DW_IC_STATUS, &status);
|
||||
if ((stat & DW_IC_INTR_TX_ABRT) || dev->msg_err ||
|
||||
|
||||
if ((stat & (DW_IC_INTR_TX_ABRT|DW_IC_INTR_RX_OVER))|| dev->msg_err ||
|
||||
((status & DW_IC_STATUS_TFE) &&
|
||||
(!(status & DW_IC_STATUS_RFNE)) &&
|
||||
(!(status & DW_IC_STATUS_MASTER_ACTIVITY)))) {
|
||||
dev->laststat = stat;
|
||||
dev->laststatus = status;
|
||||
complete(&dev->cmd_complete);
|
||||
dev->laststat = stat;
|
||||
dev->laststatus = status;
|
||||
} else if (unlikely(dev->flags & ACCESS_INTR_MASK)) {
|
||||
/* Workaround to trigger pending interrupt */
|
||||
regmap_read(dev->map, DW_IC_INTR_MASK, &stat);
|
||||
@@ -690,7 +710,8 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
|
||||
{
|
||||
struct dw_i2c_dev *dev = dev_id;
|
||||
u32 stat, enabled;
|
||||
|
||||
if (pm_runtime_suspended(dev->dev))
|
||||
return IRQ_NONE;
|
||||
regmap_read(dev->map, DW_IC_ENABLE, &enabled);
|
||||
regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &stat);
|
||||
dev_dbg(dev->dev, "enabled=%#x stat=%#x\n", enabled, stat);
|
||||
|
||||
@@ -267,6 +267,25 @@ error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int i2x_dw_get_read_size(struct dw_i2c_dev *dev)
|
||||
{
|
||||
struct i2c_msg *msgs = dev->msgs;
|
||||
u32 addr = msgs[dev->msg_write_idx].addr;
|
||||
int i = 0;
|
||||
int len = 0;
|
||||
__dev_vdgb(dev->dev, "%s, %d, enter\n", __func__, __LINE__);
|
||||
for (i = dev->msg_write_idx; i < dev->msgs_num; i++) {
|
||||
if (msgs[i].addr != addr) {
|
||||
dev_err(dev->dev, "%s: invalid target address\n", __func__);
|
||||
dev->msg_err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
if(msgs[i].flags & I2C_M_RD)
|
||||
len += msgs[i].len;
|
||||
}
|
||||
__dev_vdgb(dev->dev, "%s, %d, exit\n", __func__, __LINE__);
|
||||
return len;
|
||||
}
|
||||
int i2c_dw_xfer_dma_init(struct dw_i2c_dev *dev)
|
||||
{
|
||||
struct i2c_dw_dma *dma = &dev->dma;
|
||||
@@ -275,6 +294,9 @@ int i2c_dw_xfer_dma_init(struct dw_i2c_dev *dev)
|
||||
// i2c dma set tx data level
|
||||
regmap_write(dev->map, DW_IC_DMA_TDLR, dev->tx_fifo_depth / 2);
|
||||
|
||||
if(i2x_dw_get_read_size(dev)>(dev->rx_fifo_depth / 2))
|
||||
regmap_write(dev->map, DW_IC_RX_TL, dev->rx_fifo_depth / 2);
|
||||
|
||||
// i2c dma tx enable
|
||||
regmap_write(dev->map, DW_IC_DMA_CR, DW_IC_DMA_CR_TXEN);
|
||||
|
||||
|
||||
@@ -2348,7 +2348,7 @@ void decoder_devfreq_record_busy(struct decoder_devfreq *devfreq)
|
||||
decoder_dev_clk_lock();
|
||||
spin_lock_irqsave(&devfreq->lock, irqflags);
|
||||
busy_count = devfreq->busy_count;
|
||||
//pr_info("record_busy:busy_count = %d\n",busy_count);
|
||||
PDEBUG("record_busy:busy_count = %d\n",busy_count);
|
||||
if(devfreq->busy_count > 0)
|
||||
{
|
||||
devfreq->busy_count++;
|
||||
@@ -2376,7 +2376,7 @@ void decoder_devfreq_record_idle(struct decoder_devfreq *devfreq)
|
||||
if (!devfreq)
|
||||
return;
|
||||
spin_lock_irqsave(&devfreq->lock, irqflags);
|
||||
//pr_info("record_idle:busy_count = %d\n",devfreq->busy_count);
|
||||
PDEBUG("record_idle:busy_count = %d\n",devfreq->busy_count);
|
||||
if(devfreq->busy_count > 1)
|
||||
{
|
||||
devfreq->busy_count--;
|
||||
@@ -2581,7 +2581,7 @@ int decoder_devfreq_init(struct device *dev)
|
||||
int ret = 0;
|
||||
struct decoder_devfreq *devfreq = decoder_get_devfreq_priv_data();
|
||||
|
||||
memset(devfreq,sizeof(struct decoder_devfreq),0);
|
||||
memset(devfreq,0,sizeof(struct decoder_devfreq));
|
||||
spin_lock_init(&devfreq->lock);
|
||||
init_waitqueue_head(&devfreq->target_freq_wait_queue);
|
||||
mutex_init(&devfreq->clk_mutex);
|
||||
|
||||
@@ -1425,7 +1425,7 @@ static enum MMUStatus MMUMemNodeMap(struct addr_desc *addr, struct file *filp) {
|
||||
page_count = (addr->size - 1)/PAGE_SIZE + 1;
|
||||
|
||||
GetPhysicalAddress(addr->virtual_address, &address);
|
||||
MMUDEBUG(" *****MMU map address*****%x\n", address);
|
||||
MMUDEBUG(" *****MMU map address*****%llx phys_to_virt %lx\n", address,(unsigned long)phys_to_virt(address));
|
||||
if(address >= REGION_IN_START &&
|
||||
address + addr->size < REGION_IN_END)
|
||||
e = MMU_REGION_IN;
|
||||
@@ -1505,7 +1505,7 @@ static enum MMUStatus MMUMemNodeMap(struct addr_desc *addr, struct file *filp) {
|
||||
MMUDEBUG(" MMU_MTLB_SHIFT %d MMU_STLB_4K_SHIFT %d\n", MMU_MTLB_SHIFT, MMU_STLB_4K_SHIFT);
|
||||
MMUDEBUG(" MMUMemNodeMap map total %d pages in region %d\nMTLB/STLB starts %d/%d, MTLB/STLB ends %d/%d\n",
|
||||
page_count, (u32)e, p->mtlb_start, p->stlb_start, p->mtlb_end, p->stlb_end);
|
||||
MMUDEBUG(" MMUMemNodeMap map %p -> 0x%08x\n", addr->virtual_address, addr->bus_address);
|
||||
MMUDEBUG(" MMUMemNodeMap map %px -> 0x%08x\n", addr->virtual_address, addr->bus_address);
|
||||
|
||||
ReleaseMutex(g_mmu->page_table_mutex);
|
||||
|
||||
|
||||
@@ -580,6 +580,7 @@ struct process_manager_obj
|
||||
u64 total_exe_time;
|
||||
spinlock_t spinlock;
|
||||
u32 pm_count;
|
||||
|
||||
wait_queue_head_t wait_queue;
|
||||
} ;
|
||||
|
||||
@@ -602,7 +603,7 @@ struct cmdbuf_obj
|
||||
u16 cmdbuf_id; //used to manage CMDBUF in driver.It is a handle to identify cmdbuf.also is an interrupt vector.position in pool,same as status position.
|
||||
u8 cmdbuf_data_loaded; //0 means sw has not copied data into this CMDBUF; 1 means sw has copied data into this CMDBUF
|
||||
u8 cmdbuf_data_linked; //0 :not linked, 1:linked.
|
||||
u8 cmdbuf_run_done; //if 0,waiting for CMDBUF finish; if 1, op code in CMDBUF has finished one by one. HANTRO_VCMD_IOCH_WAIT_CMDBUF will check this variable.
|
||||
volatile u8 cmdbuf_run_done; //if 0,waiting for CMDBUF finish; if 1, op code in CMDBUF has finished one by one. HANTRO_VCMD_IOCH_WAIT_CMDBUF will check this variable.
|
||||
u8 cmdbuf_need_remove; // if 0, not need to remove CMDBUF; 1 CMDBUF can be removed if it is not the last CMDBUF;
|
||||
u32 waited; // if 0, the cmd buf hasn't been waited, otherwise, has been waited.
|
||||
u8 has_end_cmdbuf; //if 1, the last opcode is end opCode.
|
||||
@@ -896,8 +897,47 @@ static void free_cmdbuf_mem(u16 cmdbuf_id )
|
||||
spin_lock_irqsave(&vcmd_cmdbuf_alloc_lock, flags);
|
||||
cmdbuf_used[cmdbuf_id]=0;
|
||||
cmdbuf_used_residual +=1;
|
||||
PDEBUG(" ## real free cmdbuf[%d]\n",cmdbuf_id);
|
||||
spin_unlock_irqrestore(&vcmd_cmdbuf_alloc_lock, flags);
|
||||
wake_up_interruptible_all(&vcmd_cmdbuf_memory_wait);
|
||||
wake_up_all(&vcmd_cmdbuf_memory_wait);
|
||||
}
|
||||
|
||||
static void free_cmdbuf_not_linked_by_flip(struct file *filp)
|
||||
{
|
||||
unsigned long flags;
|
||||
int i;
|
||||
struct cmdbuf_obj* cmdbuf_obj;
|
||||
bi_list_node* new_cmdbuf_node;
|
||||
bool freed_flag = false;
|
||||
spin_lock_irqsave(&vcmd_cmdbuf_alloc_lock, flags);
|
||||
|
||||
for(i = 0; i < TOTAL_DISCRETE_CMDBUF_NUM; i++)
|
||||
{
|
||||
if(cmdbuf_used[i] && global_cmdbuf_node[i] != NULL)
|
||||
{
|
||||
new_cmdbuf_node = global_cmdbuf_node[i];
|
||||
if(new_cmdbuf_node == 0x55555555)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
cmdbuf_obj = (struct cmdbuf_obj* )new_cmdbuf_node->data;
|
||||
if(cmdbuf_obj->filp == filp && !cmdbuf_obj->cmdbuf_data_linked && !cmdbuf_obj->cmdbuf_run_done)
|
||||
{
|
||||
cmdbuf_used[i]=0;
|
||||
cmdbuf_used_residual +=1;
|
||||
global_cmdbuf_node[i] = NULL;
|
||||
freed_flag = true;
|
||||
PDEBUG(" ## Find left node not freed,real free cmdbuf[%d],remain %d\n",i,cmdbuf_used_residual);
|
||||
}
|
||||
}
|
||||
|
||||
if(cmdbuf_used_residual >= (TOTAL_DISCRETE_CMDBUF_NUM-2))
|
||||
break;
|
||||
|
||||
}
|
||||
spin_unlock_irqrestore(&vcmd_cmdbuf_alloc_lock, flags);
|
||||
if(freed_flag)
|
||||
wake_up_all(&vcmd_cmdbuf_memory_wait);
|
||||
}
|
||||
|
||||
static bi_list_node* create_cmdbuf_node(void)
|
||||
@@ -907,8 +947,13 @@ static bi_list_node* create_cmdbuf_node(void)
|
||||
struct noncache_mem new_cmdbuf_addr;
|
||||
struct noncache_mem new_status_cmdbuf_addr;
|
||||
|
||||
if(wait_event_interruptible(vcmd_cmdbuf_memory_wait, allocate_cmdbuf(&new_cmdbuf_addr,&new_status_cmdbuf_addr)) )
|
||||
if(!wait_event_interruptible_timeout(vcmd_cmdbuf_memory_wait, allocate_cmdbuf(&new_cmdbuf_addr,&new_status_cmdbuf_addr),
|
||||
msecs_to_jiffies(500)) )
|
||||
{
|
||||
pr_err("wait allocate_cmdbuf timeout\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef DYNAMIC_MALLOC_VCMDNODE
|
||||
cmdbuf_obj=create_cmdbuf_obj();
|
||||
#else
|
||||
@@ -1028,18 +1073,21 @@ static u64 calculate_executing_time_after_node_high_priority(bi_list_node* exe_c
|
||||
}
|
||||
return time_run_all;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_CMDBUF_ALLOC
|
||||
int cmdbuf_node_unexpected[TOTAL_DISCRETE_CMDBUF_NUM];
|
||||
#endif
|
||||
/**********************************************************************************************************\
|
||||
*cmdbuf pool management
|
||||
\***********************************************************************************************************/
|
||||
static int allocate_cmdbuf(struct noncache_mem* new_cmdbuf_addr,struct noncache_mem* new_status_cmdbuf_addr)
|
||||
{
|
||||
unsigned long flags;
|
||||
u16 cmdbuf_used_pos_start = cmdbuf_used_pos;
|
||||
spin_lock_irqsave(&vcmd_cmdbuf_alloc_lock, flags);
|
||||
if(cmdbuf_used_residual==0)
|
||||
{
|
||||
spin_unlock_irqrestore(&vcmd_cmdbuf_alloc_lock, flags);
|
||||
pr_err("%s:no empty cmdbuf\n",__func__);
|
||||
//no empty cmdbuf
|
||||
return 0;
|
||||
}
|
||||
@@ -1060,6 +1108,7 @@ static int allocate_cmdbuf(struct noncache_mem* new_cmdbuf_addr,struct noncache
|
||||
new_status_cmdbuf_addr->mmu_bus_address=vcmd_status_buf_mem_pool.mmu_bus_address + cmdbuf_used_pos*CMDBUF_MAX_SIZE;
|
||||
new_status_cmdbuf_addr->size=CMDBUF_MAX_SIZE;
|
||||
new_status_cmdbuf_addr->cmdbuf_id = cmdbuf_used_pos;
|
||||
global_cmdbuf_node[cmdbuf_used_pos]=0x55555555; //temp set it,for another thread not hit cmdbuf_used[x] set but global_cmdbuf_node[x] is null
|
||||
cmdbuf_used_pos++;
|
||||
if(cmdbuf_used_pos>=TOTAL_DISCRETE_CMDBUF_NUM)
|
||||
cmdbuf_used_pos=0;
|
||||
@@ -1068,11 +1117,30 @@ static int allocate_cmdbuf(struct noncache_mem* new_cmdbuf_addr,struct noncache
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG_CMDBUF_ALLOC
|
||||
if(cmdbuf_used[cmdbuf_used_pos]==0 && (global_cmdbuf_node[cmdbuf_used_pos]!=NULL ) && (cmdbuf_node_unexpected[cmdbuf_used_pos] == 0x55))
|
||||
{
|
||||
pr_warn("unexpected cmdbuf_used[%d] is 0,but global_cmdbuf_node[%d] != NULL\n",
|
||||
cmdbuf_used_pos,cmdbuf_used_pos);
|
||||
cmdbuf_node_unexpected[cmdbuf_used_pos] = 0x55;
|
||||
}
|
||||
else if(cmdbuf_used[cmdbuf_used_pos]!=0 && (global_cmdbuf_node[cmdbuf_used_pos] == NULL ) && (cmdbuf_node_unexpected[cmdbuf_used_pos] == 0x55))
|
||||
{
|
||||
pr_warn("unexpected cmdbuf_used[%d] != 0,but global_cmdbuf_node[%d] is NULL\n",
|
||||
cmdbuf_used_pos,cmdbuf_used_pos);
|
||||
cmdbuf_node_unexpected[cmdbuf_used_pos] = 0x55;
|
||||
}
|
||||
#endif
|
||||
cmdbuf_used_pos++;
|
||||
if(cmdbuf_used_pos>=TOTAL_DISCRETE_CMDBUF_NUM)
|
||||
cmdbuf_used_pos=0;
|
||||
|
||||
if(cmdbuf_used_pos_start == cmdbuf_used_pos) //searched all,not find one,should return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&vcmd_cmdbuf_alloc_lock, flags);
|
||||
pr_err("%s: no cmdbuf found,cmdbuf_used_residual %d\n",__func__,cmdbuf_used_residual);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1113,7 +1181,9 @@ static int select_vcmd(bi_list_node* new_cmdbuf_node)
|
||||
size_t exe_cmdbuf_addr=0;
|
||||
struct cmdbuf_obj* cmdbuf_obj_temp=NULL;
|
||||
u32 cmdbuf_id=0;
|
||||
struct process_manager_obj* process_manager_temp;
|
||||
cmdbuf_obj=(struct cmdbuf_obj*)new_cmdbuf_node->data;
|
||||
|
||||
//there is an empty vcmd to be used
|
||||
while(1)
|
||||
{
|
||||
@@ -1446,7 +1516,7 @@ static long reserve_cmdbuf(struct file *filp,struct exchange_parameter* input_pa
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
PDEBUG("reserve cmdbuf filp %p\n", (void *)filp);
|
||||
PDEBUG("reserve cmdbuf filp %px\n", (void *)filp);
|
||||
spin_lock_irqsave(&vcmd_process_manager_lock, flags);
|
||||
process_manager_node = global_process_manager.head;
|
||||
while(1)
|
||||
@@ -1459,7 +1529,7 @@ static long reserve_cmdbuf(struct file *filp,struct exchange_parameter* input_pa
|
||||
return -1;
|
||||
}
|
||||
process_manager_obj = (struct process_manager_obj*)process_manager_node->data;
|
||||
PDEBUG("reserve loop: node %p, filp %p\n", (void *)process_manager_node,
|
||||
PDEBUG("reserve loop: node %px, filp %px\n", (void *)process_manager_node,
|
||||
(void *)process_manager_obj->filp);
|
||||
if (filp == process_manager_obj->filp)
|
||||
break;
|
||||
@@ -1470,13 +1540,19 @@ static long reserve_cmdbuf(struct file *filp,struct exchange_parameter* input_pa
|
||||
spin_lock_irqsave(&process_manager_obj->spinlock, flags);
|
||||
process_manager_obj->total_exe_time += input_para->executing_time;
|
||||
spin_unlock_irqrestore(&process_manager_obj->spinlock, flags);
|
||||
if(wait_event_interruptible(process_manager_obj->wait_queue, wait_process_resource_rdy(process_manager_obj)))
|
||||
return -1;
|
||||
if(!wait_event_interruptible_timeout(process_manager_obj->wait_queue, wait_process_resource_rdy(process_manager_obj),
|
||||
msecs_to_jiffies(500) ))
|
||||
{
|
||||
pr_err("wait_process_resource_rdy timeout! total_exe_time %lld\n",process_manager_obj->total_exe_time);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
new_cmdbuf_node=create_cmdbuf_node();
|
||||
if(new_cmdbuf_node==NULL)
|
||||
return -1;
|
||||
|
||||
|
||||
cmdbuf_obj = (struct cmdbuf_obj* )new_cmdbuf_node->data;
|
||||
cmdbuf_obj->module_type = input_para->module_type;
|
||||
cmdbuf_obj->priority = input_para->priority;
|
||||
@@ -1559,6 +1635,7 @@ static long release_cmdbuf(struct file *filp,u16 cmdbuf_id)
|
||||
up(&vcmd_reserve_cmdbuf_sem[module_type]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long release_cmdbuf_node(bi_list* list,bi_list_node*cmdbuf_node)
|
||||
{
|
||||
bi_list_node* new_cmdbuf_node=NULL;
|
||||
@@ -1710,7 +1787,7 @@ static long link_and_run_cmdbuf(struct file *filp,struct exchange_parameter* inp
|
||||
|
||||
dev = &hantrovcmd_data[cmdbuf_obj->core_id];
|
||||
input_para->core_id = cmdbuf_obj->core_id;
|
||||
PDEBUG("filp=%p, VCMD Link CMDBUF [%d] to core [%d]\n", (void *)filp, cmdbuf_id, input_para->core_id);
|
||||
PDEBUG("filp=%px, VCMD Link CMDBUF [%d] to core [%d]\n", (void *)filp, cmdbuf_id, input_para->core_id);
|
||||
//set ddr address for vcmd registers copy.
|
||||
if(dev->hw_version_id > HW_ID_1_0_C )
|
||||
{
|
||||
@@ -1953,11 +2030,11 @@ static unsigned int wait_cmdbuf_ready(struct file *filp,u16 cmdbuf_id,u32 *irq_s
|
||||
check_cmdbuf_irq(dev,cmdbuf_obj,irq_status_ret),msecs_to_jiffies(500))
|
||||
)
|
||||
{
|
||||
pr_err("vcmd_wait_queue_0 timeout");
|
||||
pr_err("vcmd_wait_queue_0 timeout cmdbuf[%d]\n",cmdbuf_id);
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
PDEBUG("filp=%p, VCMD Wait CMDBUF [%d]\n", (void *)filp, cmdbuf_id);
|
||||
PDEBUG("filp=%px, VCMD Wait CMDBUF [%d]\n", (void *)filp, cmdbuf_id);
|
||||
return 0;
|
||||
} else {
|
||||
if (check_mc_cmdbuf_irq(filp, cmdbuf_obj, irq_status_ret))
|
||||
@@ -2096,7 +2173,7 @@ long hantrovcmd_ioctl(struct file *filp,
|
||||
ret = reserve_cmdbuf(filp,&input_para);
|
||||
if (ret == 0)
|
||||
copy_to_user((struct exchange_parameter*)arg,&input_para,sizeof(struct exchange_parameter));
|
||||
PDEBUG("filp=%p, VCMD Reserve CMDBUF [%d]\n", (void *)filp, input_para.cmdbuf_id);
|
||||
PDEBUG("filp=%px, VCMD Reserve CMDBUF [%d] remain %d \n", (void *)filp, input_para.cmdbuf_id,cmdbuf_used_residual);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2106,7 +2183,7 @@ long hantrovcmd_ioctl(struct file *filp,
|
||||
long retVal;
|
||||
copy_from_user(&input_para,(struct exchange_parameter*)arg,sizeof(struct exchange_parameter));
|
||||
|
||||
PDEBUG("filp=%p,VCMD link and run cmdbuf,[%d] \n",(void *)filp, input_para.cmdbuf_id);
|
||||
PDEBUG("filp=%px,VCMD link and run cmdbuf,[%d] \n",(void *)filp, input_para.cmdbuf_id);
|
||||
|
||||
if (process_manager_obj)
|
||||
process_manager_obj->pm_count++;
|
||||
@@ -2126,11 +2203,11 @@ long hantrovcmd_ioctl(struct file *filp,
|
||||
__get_user(cmdbuf_id, (u16*)arg);
|
||||
/*high 16 bits are core id, low 16 bits are cmdbuf_id*/
|
||||
|
||||
PDEBUG("filp=%p,VCMD wait for CMDBUF finishing. %d,\n",filp,cmdbuf_id);
|
||||
PDEBUG("filp=%px,VCMD wait for CMDBUF finishing. %d,\n",filp,cmdbuf_id);
|
||||
|
||||
//TODO
|
||||
tmp = wait_cmdbuf_ready(filp,cmdbuf_id,&irq_status_ret);
|
||||
PDEBUG("filp=%p,VCMD wait for CMDBUF finished. %d,\n",filp,cmdbuf_id);
|
||||
PDEBUG("filp=%px,VCMD wait for CMDBUF finished. %d,\n",filp,cmdbuf_id);
|
||||
cmdbuf_id=(u16)irq_status_ret;
|
||||
if (tmp==0)
|
||||
{
|
||||
@@ -2151,11 +2228,11 @@ long hantrovcmd_ioctl(struct file *filp,
|
||||
__get_user(cmdbuf_id, (u16*)arg);
|
||||
/*16 bits are cmdbuf_id*/
|
||||
|
||||
PDEBUG("filp=%p,VCMD release CMDBUF ,%d\n",filp,cmdbuf_id);
|
||||
|
||||
if (process_manager_obj)
|
||||
process_manager_obj->pm_count--;
|
||||
release_cmdbuf(filp,cmdbuf_id);
|
||||
PDEBUG("filp=%px,VCMD release CMDBUF ,%d,remain %d \n",filp,cmdbuf_id,cmdbuf_used_residual);
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
@@ -2403,7 +2480,7 @@ int hantrovcmd_open(struct inode *inode, struct file *filp)
|
||||
filp->private_data = process_manager_node->data;
|
||||
|
||||
PDEBUG("dev opened\n");
|
||||
PDEBUG("process node %p for filp opened %p\n", (void *)process_manager_node, (void *)filp);
|
||||
PDEBUG("process node %px for filp opened %px\n", (void *)process_manager_node, (void *)filp);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2422,7 +2499,7 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
||||
unsigned long flags;
|
||||
long retVal=0;
|
||||
|
||||
PDEBUG("dev closed for process %p via hantrovcmd_release\n", (void *)filp);
|
||||
PDEBUG("dev closed for process %px via hantrovcmd_release\n", (void *)filp);
|
||||
down(&vcmd_reserve_cmdbuf_sem[dev->vcmd_core_cfg.sub_module_type]);
|
||||
|
||||
for (core_id = 0;core_id < total_vcmd_core_num; core_id++)
|
||||
@@ -2436,8 +2513,13 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
||||
if(new_cmdbuf_node==NULL)
|
||||
break;
|
||||
cmdbuf_obj_temp=(struct cmdbuf_obj*)new_cmdbuf_node->data;
|
||||
PDEBUG("Process %p is releasing: checking cmdbuf %d of process %p.\n",
|
||||
filp, cmdbuf_obj_temp->cmdbuf_id, cmdbuf_obj_temp->filp);
|
||||
if(cmdbuf_obj_temp->cmdbuf_id > 1)
|
||||
{
|
||||
PDEBUG("Process %px is releasing: checking cmdbuf %d (done %d,linked %d wstat %d) process %px. remain %d\n",
|
||||
filp, cmdbuf_obj_temp->cmdbuf_id, cmdbuf_obj_temp->cmdbuf_run_done,cmdbuf_obj_temp->cmdbuf_data_linked,
|
||||
dev[core_id].working_state,
|
||||
cmdbuf_obj_temp->filp,cmdbuf_used_residual);
|
||||
}
|
||||
if (dev[core_id].hwregs && (cmdbuf_obj_temp->filp == filp))
|
||||
{
|
||||
if(cmdbuf_obj_temp->cmdbuf_run_done)
|
||||
@@ -2473,105 +2555,122 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
||||
bi_list_node* done_cmdbuf_node = NULL;
|
||||
int abort_cmdbuf_id;
|
||||
int loop_count = 0;
|
||||
|
||||
//abort the vcmd and wait
|
||||
pr_info("Abort due to linked cmdbuf %d of current process.\n", cmdbuf_obj_temp->cmdbuf_id);
|
||||
printk_vcmd_register_debug((const void *)dev->hwregs, "Before trigger to 0");
|
||||
// disable abort interrupt
|
||||
//vcmd_write_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_IRQ_ABORT_EN,0);
|
||||
vcmd_write_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_START_TRIGGER,0);
|
||||
vcmd_aborted = 1;
|
||||
|
||||
printk_vcmd_register_debug((const void *)dev->hwregs,"After trigger to 0");
|
||||
// Wait vcmd core aborted and vcmd enters IDLE mode.
|
||||
//while (dev[core_id].working_state != WORKING_STATE_IDLE) {
|
||||
while (vcmd_get_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_WORK_STATE)) {
|
||||
loop_count++;
|
||||
if (!(loop_count % 10)) {
|
||||
u32 irq_status = vcmd_read_reg((const void *)dev->hwregs, VCMD_REGISTER_INT_STATUS_OFFSET);
|
||||
pr_err("hantrovcmd: expected idle state, but irq status = 0x%0x\n", irq_status);
|
||||
pr_err("hantrovcmd: vcmd current status is %d\n", vcmd_get_register_value((const void *)dev->hwregs, dev[core_id].reg_mirror, HWIF_VCMD_WORK_STATE));
|
||||
}
|
||||
mdelay(10); // wait 10ms
|
||||
if (loop_count > 100) { // too long
|
||||
pr_err("hantrovcmd: too long before vcmd core to IDLE state\n");
|
||||
|
||||
|
||||
spin_unlock_irqrestore(dev[core_id].spinlock, flags);
|
||||
pm_runtime_mark_last_busy(&dev[0].pdev->dev);
|
||||
pm_runtime_put_sync_suspend(&dev[0].pdev->dev);
|
||||
up(&vcmd_reserve_cmdbuf_sem[dev->vcmd_core_cfg.sub_module_type]);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
u32 irq_status_ret;
|
||||
|
||||
spin_unlock_irqrestore(dev[core_id].spinlock, flags);
|
||||
if(wait_event_timeout(*dev[core_id].wait_queue,
|
||||
check_cmdbuf_irq(dev,cmdbuf_obj_temp,&irq_status_ret),msecs_to_jiffies(1000))
|
||||
)
|
||||
{
|
||||
spin_lock_irqsave(dev[core_id].spinlock, flags);
|
||||
PDEBUG(" ## wait got cmdbuf[%d] done %d \n",cmdbuf_obj_temp->cmdbuf_id,cmdbuf_obj_temp->cmdbuf_run_done);
|
||||
cmdbuf_obj_temp->cmdbuf_need_remove=1;
|
||||
retVal=release_cmdbuf_node(&dev[core_id].list_manager,new_cmdbuf_node);
|
||||
if(retVal==1)
|
||||
cmdbuf_obj_temp->process_manager_obj = NULL;
|
||||
}
|
||||
dev[core_id].working_state = WORKING_STATE_IDLE;
|
||||
// clear interrupt & restore abort_e
|
||||
if (vcmd_get_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_IRQ_ABORT)) {
|
||||
PDEBUG("Abort interrupt triggered, now clear it to avoid abort int...\n");
|
||||
vcmd_write_reg((const void *)dev->hwregs, VCMD_REGISTER_INT_STATUS_OFFSET, 0x1<<4);
|
||||
PDEBUG("Now irq status = 0x%0x.\n", vcmd_read_reg((const void *)dev->hwregs, VCMD_REGISTER_INT_STATUS_OFFSET));
|
||||
}
|
||||
//printk_vcmd_register_debug((const void *)dev->hwregs, "vcmd status to IDLE");
|
||||
else
|
||||
{
|
||||
spin_lock_irqsave(dev[core_id].spinlock, flags);
|
||||
//abort the vcmd and wait
|
||||
pr_info("Abort due to linked cmdbuf %d of current process.\n", cmdbuf_obj_temp->cmdbuf_id);
|
||||
printk_vcmd_register_debug((const void *)dev->hwregs, "Before trigger to 0");
|
||||
// disable abort interrupt
|
||||
//vcmd_write_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_IRQ_ABORT_EN,0);
|
||||
vcmd_write_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_START_TRIGGER,0);
|
||||
vcmd_aborted = 1;
|
||||
|
||||
abort_cmdbuf_id = vcmd_get_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_CMDBUF_EXECUTING_ID);
|
||||
PDEBUG("Abort when executing cmd buf %d.\n", abort_cmdbuf_id);
|
||||
dev[core_id].sw_cmdbuf_rdy_num = 0;
|
||||
dev[core_id].duration_without_int = 0;
|
||||
vcmd_write_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_EXE_CMDBUF_COUNT,0);
|
||||
vcmd_write_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_RDY_CMDBUF_COUNT,0);
|
||||
printk_vcmd_register_debug((const void *)dev->hwregs,"After trigger to 0");
|
||||
// Wait vcmd core aborted and vcmd enters IDLE mode.
|
||||
//while (dev[core_id].working_state != WORKING_STATE_IDLE) {
|
||||
while (vcmd_get_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_WORK_STATE)) {
|
||||
loop_count++;
|
||||
if (!(loop_count % 10)) {
|
||||
u32 irq_status = vcmd_read_reg((const void *)dev->hwregs, VCMD_REGISTER_INT_STATUS_OFFSET);
|
||||
pr_err("hantrovcmd: expected idle state, but irq status = 0x%0x\n", irq_status);
|
||||
pr_err("hantrovcmd: vcmd current status is %d\n", vcmd_get_register_value((const void *)dev->hwregs, dev[core_id].reg_mirror, HWIF_VCMD_WORK_STATE));
|
||||
}
|
||||
mdelay(50); // wait 10ms
|
||||
if (loop_count > 100) { // too long
|
||||
pr_err("hantrovcmd: too long before vcmd core to IDLE state\n");
|
||||
|
||||
/* Mark cmdbuf_run_done to 1 for all the cmd buf executed. */
|
||||
done_cmdbuf_node = dev[core_id].list_manager.head;
|
||||
while (done_cmdbuf_node) {
|
||||
if (!((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_run_done) {
|
||||
((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_run_done = 1;
|
||||
((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_data_linked = 0;
|
||||
PDEBUG("Set cmdbuf [%d] cmdbuf_run_done to 1.\n", ((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_id);
|
||||
}
|
||||
if (((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_id == abort_cmdbuf_id)
|
||||
break;
|
||||
done_cmdbuf_node = done_cmdbuf_node->next;
|
||||
}
|
||||
if (cmdbuf_obj_temp->cmdbuf_run_done) {
|
||||
/* current cmdbuf is in fact has been executed, but due to interrupt is not triggered, the status is not updated.
|
||||
Just delink and remove it from the list. */
|
||||
if (done_cmdbuf_node && done_cmdbuf_node->data) {
|
||||
PDEBUG("done_cmdbuf_node is cmdbuf [%d].\n", ((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_id);
|
||||
}
|
||||
if (done_cmdbuf_node) {
|
||||
done_cmdbuf_node = done_cmdbuf_node->next;
|
||||
if (done_cmdbuf_node)
|
||||
restart_cmdbuf = (struct cmdbuf_obj*)done_cmdbuf_node->data;
|
||||
}
|
||||
if (restart_cmdbuf) {
|
||||
PDEBUG("Set restart cmdbuf [%d] via if.\n", restart_cmdbuf->cmdbuf_id);
|
||||
}
|
||||
} else {
|
||||
last_cmdbuf_node = new_cmdbuf_node;
|
||||
/* cmd buf num from aborted cmd buf to current cmdbuf_obj_temp */
|
||||
if (cmdbuf_obj_temp->cmdbuf_id != abort_cmdbuf_id) {
|
||||
last_cmdbuf_node = new_cmdbuf_node->previous;
|
||||
|
||||
while (last_cmdbuf_node &&
|
||||
((struct cmdbuf_obj*)last_cmdbuf_node->data)->cmdbuf_id != abort_cmdbuf_id) {
|
||||
restart_cmdbuf = (struct cmdbuf_obj*)last_cmdbuf_node->data;
|
||||
last_cmdbuf_node = last_cmdbuf_node->previous;
|
||||
dev[core_id].sw_cmdbuf_rdy_num++;
|
||||
dev[core_id].duration_without_int += restart_cmdbuf->executing_time;
|
||||
PDEBUG("Keep valid cmdbuf [%d] in the list.\n", restart_cmdbuf->cmdbuf_id);
|
||||
spin_unlock_irqrestore(dev[core_id].spinlock, flags);
|
||||
pm_runtime_mark_last_busy(&dev[0].pdev->dev);
|
||||
pm_runtime_put_sync_suspend(&dev[0].pdev->dev);
|
||||
up(&vcmd_reserve_cmdbuf_sem[dev->vcmd_core_cfg.sub_module_type]);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (restart_cmdbuf) {
|
||||
PDEBUG("Set restart cmdbuf [%d] via else.\n", restart_cmdbuf->cmdbuf_id);
|
||||
}
|
||||
}
|
||||
dev[core_id].working_state = WORKING_STATE_IDLE;
|
||||
// clear interrupt & restore abort_e
|
||||
if (vcmd_get_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_IRQ_ABORT)) {
|
||||
PDEBUG("Abort interrupt triggered, now clear it to avoid abort int...\n");
|
||||
vcmd_write_reg((const void *)dev->hwregs, VCMD_REGISTER_INT_STATUS_OFFSET, 0x1<<4);
|
||||
PDEBUG("Now irq status = 0x%0x.\n", vcmd_read_reg((const void *)dev->hwregs, VCMD_REGISTER_INT_STATUS_OFFSET));
|
||||
}
|
||||
//printk_vcmd_register_debug((const void *)dev->hwregs, "vcmd status to IDLE");
|
||||
|
||||
// remove first linked cmdbuf from list
|
||||
vcmd_delink_rm_cmdbuf(&dev[core_id], new_cmdbuf_node);
|
||||
abort_cmdbuf_id = vcmd_get_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_CMDBUF_EXECUTING_ID);
|
||||
PDEBUG("Abort when executing cmd buf %d.\n", abort_cmdbuf_id);
|
||||
dev[core_id].sw_cmdbuf_rdy_num = 0;
|
||||
dev[core_id].duration_without_int = 0;
|
||||
vcmd_write_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_EXE_CMDBUF_COUNT,0);
|
||||
vcmd_write_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_RDY_CMDBUF_COUNT,0);
|
||||
|
||||
/* Mark cmdbuf_run_done to 1 for all the cmd buf executed. */
|
||||
done_cmdbuf_node = dev[core_id].list_manager.head;
|
||||
while (done_cmdbuf_node) {
|
||||
if (!((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_run_done) {
|
||||
((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_run_done = 1;
|
||||
((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_data_linked = 0;
|
||||
PDEBUG("Set cmdbuf [%d] cmdbuf_run_done to 1.\n", ((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_id);
|
||||
}
|
||||
if (((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_id == abort_cmdbuf_id)
|
||||
break;
|
||||
done_cmdbuf_node = done_cmdbuf_node->next;
|
||||
}
|
||||
if (cmdbuf_obj_temp->cmdbuf_run_done) {
|
||||
/* current cmdbuf is in fact has been executed, but due to interrupt is not triggered, the status is not updated.
|
||||
Just delink and remove it from the list. */
|
||||
if (done_cmdbuf_node && done_cmdbuf_node->data) {
|
||||
PDEBUG("done_cmdbuf_node is cmdbuf [%d].\n", ((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_id);
|
||||
}
|
||||
if (done_cmdbuf_node) {
|
||||
done_cmdbuf_node = done_cmdbuf_node->next;
|
||||
if (done_cmdbuf_node)
|
||||
restart_cmdbuf = (struct cmdbuf_obj*)done_cmdbuf_node->data;
|
||||
}
|
||||
if (restart_cmdbuf) {
|
||||
PDEBUG("Set restart cmdbuf [%d] via if.\n", restart_cmdbuf->cmdbuf_id);
|
||||
}
|
||||
} else {
|
||||
last_cmdbuf_node = new_cmdbuf_node;
|
||||
/* cmd buf num from aborted cmd buf to current cmdbuf_obj_temp */
|
||||
if (cmdbuf_obj_temp->cmdbuf_id != abort_cmdbuf_id) {
|
||||
last_cmdbuf_node = new_cmdbuf_node->previous;
|
||||
|
||||
while (last_cmdbuf_node &&
|
||||
((struct cmdbuf_obj*)last_cmdbuf_node->data)->cmdbuf_id != abort_cmdbuf_id) {
|
||||
restart_cmdbuf = (struct cmdbuf_obj*)last_cmdbuf_node->data;
|
||||
last_cmdbuf_node = last_cmdbuf_node->previous;
|
||||
dev[core_id].sw_cmdbuf_rdy_num++;
|
||||
dev[core_id].duration_without_int += restart_cmdbuf->executing_time;
|
||||
PDEBUG("Keep valid cmdbuf [%d] in the list.\n", restart_cmdbuf->cmdbuf_id);
|
||||
}
|
||||
}
|
||||
if (restart_cmdbuf) {
|
||||
PDEBUG("Set restart cmdbuf [%d] via else.\n", restart_cmdbuf->cmdbuf_id);
|
||||
}
|
||||
}
|
||||
|
||||
// remove first linked cmdbuf from list
|
||||
vcmd_delink_rm_cmdbuf(&dev[core_id], new_cmdbuf_node);
|
||||
}
|
||||
|
||||
}
|
||||
release_cmdbuf_num++;
|
||||
PDEBUG("release reserved cmdbuf\n");
|
||||
PDEBUG("release reserved cmdbuf,remain %d\n",cmdbuf_used_residual);
|
||||
} else if (vcmd_aborted && !cmdbuf_obj_temp->cmdbuf_run_done) {
|
||||
/* VCMD is aborted, need to re-calculate the duration_without_int */
|
||||
if (!restart_cmdbuf)
|
||||
@@ -2630,7 +2729,12 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
||||
}
|
||||
|
||||
if(release_cmdbuf_num)
|
||||
wake_up_interruptible_all(&vcmd_cmdbuf_memory_wait);
|
||||
wake_up_all(&vcmd_cmdbuf_memory_wait);
|
||||
|
||||
// free reserved but unlinkd node
|
||||
// Here is powerfull free all this process reserved/linked cmdbuf
|
||||
free_cmdbuf_not_linked_by_flip(filp);
|
||||
|
||||
spin_lock_irqsave(&vcmd_process_manager_lock, flags);
|
||||
process_manager_node = global_process_manager.head;
|
||||
while(1)
|
||||
@@ -2642,10 +2746,10 @@ int hantrovcmd_release(struct inode *inode, struct file *filp)
|
||||
break;
|
||||
process_manager_node = process_manager_node->next;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//remove node from list
|
||||
PDEBUG("process node %p for filp to be removed: %p\n", (void *)process_manager_node, (void *)process_manager_obj->filp);
|
||||
PDEBUG("process node %px for filp to be removed: %px remain %d\n", (void *)process_manager_node, (void *)process_manager_obj->filp,cmdbuf_used_residual);
|
||||
bi_list_remove_node(&global_process_manager,process_manager_node);
|
||||
spin_unlock_irqrestore(&vcmd_process_manager_lock, flags);
|
||||
free_process_manager_node(process_manager_node);
|
||||
@@ -3140,7 +3244,7 @@ static void read_main_module_all_registers(u32 main_module_type)
|
||||
//msleep(1000);
|
||||
hantrovcmd_isr(input_para.core_id, &hantrovcmd_data[input_para.core_id]);
|
||||
wait_cmdbuf_ready(NULL,input_para.cmdbuf_id,&irq_status_ret);
|
||||
decoder_devfreq_record_idle( decoder_get_devfreq_priv_data() );
|
||||
pr_info("%s:record_idle:busy_count = %d\n",__func__,decoder_get_devfreq_priv_data()->busy_count);
|
||||
status_base_virt_addr=vcmd_status_buf_mem_pool.virtualAddress + input_para.cmdbuf_id*CMDBUF_MAX_SIZE/4+(vcmd_manager[input_para.module_type][0]->vcmd_core_cfg.submodule_main_addr/2/4+0);
|
||||
pr_info("vc8000_vcmd_driver: main module register 0:0x%x\n",*status_base_virt_addr);
|
||||
pr_info("vc8000_vcmd_driver: main module register 50:0x%08x\n",*(status_base_virt_addr+50));
|
||||
@@ -3293,6 +3397,7 @@ int hantrovcmd_init(struct platform_device *pdev)
|
||||
cmdbuf_used_pos=1;
|
||||
cmdbuf_used[0]=1;
|
||||
cmdbuf_used_residual -=1;
|
||||
pr_info(" CMDBUF[0] reserved,remain %d\n",cmdbuf_used_residual);
|
||||
|
||||
create_kernel_process_manager();
|
||||
for(i=0;i<MAX_VCMD_TYPE;i++)
|
||||
@@ -3618,7 +3723,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id)
|
||||
new_cmdbuf_node = global_cmdbuf_node[cmdbuf_id];
|
||||
if(new_cmdbuf_node==NULL)
|
||||
{
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id !!\n");
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id %d line %d!!\n",cmdbuf_id,__LINE__);
|
||||
spin_unlock_irqrestore(dev->spinlock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -3681,7 +3786,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id)
|
||||
new_cmdbuf_node = global_cmdbuf_node[cmdbuf_id];
|
||||
if(new_cmdbuf_node==NULL)
|
||||
{
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id !!\n");
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id %d line %d!!\n",cmdbuf_id,__LINE__);
|
||||
spin_unlock_irqrestore(dev->spinlock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -3754,7 +3859,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id)
|
||||
new_cmdbuf_node = global_cmdbuf_node[cmdbuf_id];
|
||||
if(new_cmdbuf_node==NULL)
|
||||
{
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id !!\n");
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id %d line %d!!\n",cmdbuf_id,__LINE__);
|
||||
spin_unlock_irqrestore(dev->spinlock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -3823,7 +3928,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id)
|
||||
new_cmdbuf_node = global_cmdbuf_node[cmdbuf_id];
|
||||
if(new_cmdbuf_node==NULL)
|
||||
{
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id !!\n");
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id %d line %d!!\n",cmdbuf_id,__LINE__);
|
||||
spin_unlock_irqrestore(dev->spinlock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -3896,7 +4001,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id)
|
||||
new_cmdbuf_node = global_cmdbuf_node[cmdbuf_id];
|
||||
if(new_cmdbuf_node==NULL)
|
||||
{
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id !!\n");
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id %d line %d!!\n",cmdbuf_id,__LINE__);
|
||||
spin_unlock_irqrestore(dev->spinlock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -3967,7 +4072,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id)
|
||||
new_cmdbuf_node = global_cmdbuf_node[cmdbuf_id];
|
||||
if(new_cmdbuf_node==NULL)
|
||||
{
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id !!\n");
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id %d line %d!!\n",cmdbuf_id,__LINE__);
|
||||
spin_unlock_irqrestore(dev->spinlock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -634,7 +634,7 @@ struct cmdbuf_obj
|
||||
u16 cmdbuf_id; //used to manage CMDBUF in driver.It is a handle to identify cmdbuf.also is an interrupt vector.position in pool,same as status position.
|
||||
u8 cmdbuf_data_loaded; //0 means sw has not copied data into this CMDBUF; 1 means sw has copied data into this CMDBUF
|
||||
u8 cmdbuf_data_linked; //0 :not linked, 1:linked.into a vcmd core list.
|
||||
u8 cmdbuf_run_done; //if 0,waiting for CMDBUF finish; if 1, op code in CMDBUF has finished one by one. HANTRO_VCMD_IOCH_WAIT_CMDBUF will check this variable.
|
||||
volatile u8 cmdbuf_run_done; //if 0,waiting for CMDBUF finish; if 1, op code in CMDBUF has finished one by one. HANTRO_VCMD_IOCH_WAIT_CMDBUF will check this variable.
|
||||
u8 cmdbuf_need_remove; // if 0, not need to remove CMDBUF; 1 CMDBUF can be removed if it is not the last CMDBUF;
|
||||
u8 has_end_cmdbuf; //if 1, the last opcode is end opCode.
|
||||
u8 no_normal_int_cmdbuf; //if 1, JMP will not send normal interrupt.
|
||||
@@ -930,8 +930,47 @@ static void free_cmdbuf_mem(u16 cmdbuf_id )
|
||||
spin_lock_irqsave(&vcmd_cmdbuf_alloc_lock, flags);
|
||||
cmdbuf_used[cmdbuf_id]=0;
|
||||
cmdbuf_used_residual +=1;
|
||||
PDEBUG(" ## real free cmdbuf[%d]\n",cmdbuf_id);
|
||||
spin_unlock_irqrestore(&vcmd_cmdbuf_alloc_lock, flags);
|
||||
wake_up_interruptible_all(&vcmd_cmdbuf_memory_wait);
|
||||
wake_up_all(&vcmd_cmdbuf_memory_wait);
|
||||
}
|
||||
|
||||
static void free_cmdbuf_not_linked_by_flip(struct file *filp)
|
||||
{
|
||||
unsigned long flags;
|
||||
int i;
|
||||
struct cmdbuf_obj* cmdbuf_obj;
|
||||
bi_list_node* new_cmdbuf_node;
|
||||
bool freed_flag = false;
|
||||
spin_lock_irqsave(&vcmd_cmdbuf_alloc_lock, flags);
|
||||
|
||||
for(i = 0; i < TOTAL_DISCRETE_CMDBUF_NUM; i++)
|
||||
{
|
||||
if(cmdbuf_used[i] && global_cmdbuf_node[i] != NULL)
|
||||
{
|
||||
new_cmdbuf_node = global_cmdbuf_node[i];
|
||||
if(new_cmdbuf_node == 0x55555555)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
cmdbuf_obj = (struct cmdbuf_obj* )new_cmdbuf_node->data;
|
||||
if(cmdbuf_obj->filp == filp && !cmdbuf_obj->cmdbuf_data_linked && !cmdbuf_obj->cmdbuf_run_done)
|
||||
{
|
||||
cmdbuf_used[i]=0;
|
||||
cmdbuf_used_residual +=1;
|
||||
global_cmdbuf_node[i] = NULL;
|
||||
freed_flag = true;
|
||||
PDEBUG(" ## Find left node not freed,real free cmdbuf[%d],remain %d\n",i,cmdbuf_used_residual);
|
||||
}
|
||||
}
|
||||
|
||||
if(cmdbuf_used_residual >= (TOTAL_DISCRETE_CMDBUF_NUM-2))
|
||||
break;
|
||||
|
||||
}
|
||||
spin_unlock_irqrestore(&vcmd_cmdbuf_alloc_lock, flags);
|
||||
if(freed_flag)
|
||||
wake_up_all(&vcmd_cmdbuf_memory_wait);
|
||||
}
|
||||
|
||||
static bi_list_node* create_cmdbuf_node(void)
|
||||
@@ -941,8 +980,13 @@ static bi_list_node* create_cmdbuf_node(void)
|
||||
struct noncache_mem new_cmdbuf_addr;
|
||||
struct noncache_mem new_status_cmdbuf_addr;
|
||||
|
||||
if(wait_event_interruptible(vcmd_cmdbuf_memory_wait, allocate_cmdbuf(&new_cmdbuf_addr,&new_status_cmdbuf_addr)) )
|
||||
if(!wait_event_interruptible_timeout(vcmd_cmdbuf_memory_wait, allocate_cmdbuf(&new_cmdbuf_addr,&new_status_cmdbuf_addr),
|
||||
msecs_to_jiffies(500)) )
|
||||
{
|
||||
pr_err("vc8000e: wait allocate_cmdbuf timeout\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cmdbuf_obj = create_vcmd_cmdbuf_obj(new_cmdbuf_addr.cmdbuf_id);
|
||||
if(cmdbuf_obj==NULL)
|
||||
{
|
||||
@@ -1048,18 +1092,21 @@ static u32 calculate_executing_time_after_node_high_priority(bi_list_node* exe_c
|
||||
}
|
||||
return time_run_all;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_CMDBUF_ALLOC
|
||||
int cmdbuf_node_unexpected[TOTAL_DISCRETE_CMDBUF_NUM];
|
||||
#endif
|
||||
/**********************************************************************************************************\
|
||||
*cmdbuf pool management
|
||||
\***********************************************************************************************************/
|
||||
static int allocate_cmdbuf(struct noncache_mem* new_cmdbuf_addr,struct noncache_mem* new_status_cmdbuf_addr)
|
||||
{
|
||||
unsigned long flags;
|
||||
u16 cmdbuf_used_pos_start = cmdbuf_used_pos;
|
||||
spin_lock_irqsave(&vcmd_cmdbuf_alloc_lock, flags);
|
||||
if(cmdbuf_used_residual==0)
|
||||
{
|
||||
spin_unlock_irqrestore(&vcmd_cmdbuf_alloc_lock, flags);
|
||||
pr_err("%s:vc8000e:no empty cmdbuf\n",__func__);
|
||||
//no empty cmdbuf
|
||||
return 0;
|
||||
}
|
||||
@@ -1080,6 +1127,7 @@ static int allocate_cmdbuf(struct noncache_mem* new_cmdbuf_addr,struct noncache
|
||||
new_status_cmdbuf_addr->mmu_bus_address=vcmd_status_buf_mem_pool.mmu_bus_address + cmdbuf_used_pos*CMDBUF_MAX_SIZE;
|
||||
new_status_cmdbuf_addr->size=CMDBUF_MAX_SIZE;
|
||||
new_status_cmdbuf_addr->cmdbuf_id = cmdbuf_used_pos;
|
||||
global_cmdbuf_node[cmdbuf_used_pos]=0x55555555; //temp set it,for another thread not hit cmdbuf_used[x] set but global_cmdbuf_node[x] is null
|
||||
cmdbuf_used_pos++;
|
||||
if(cmdbuf_used_pos>=TOTAL_DISCRETE_CMDBUF_NUM)
|
||||
cmdbuf_used_pos=0;
|
||||
@@ -1088,11 +1136,30 @@ static int allocate_cmdbuf(struct noncache_mem* new_cmdbuf_addr,struct noncache
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG_CMDBUF_ALLOC
|
||||
if(cmdbuf_used[cmdbuf_used_pos]==0 && (global_cmdbuf_node[cmdbuf_used_pos]!=NULL ) && (cmdbuf_node_unexpected[cmdbuf_used_pos] == 0x55))
|
||||
{
|
||||
pr_warn("vc8000e:unexpected cmdbuf_used[%d] is 0,but global_cmdbuf_node[%d] != NULL\n",
|
||||
cmdbuf_used_pos,cmdbuf_used_pos);
|
||||
cmdbuf_node_unexpected[cmdbuf_used_pos] = 0x55;
|
||||
}
|
||||
else if(cmdbuf_used[cmdbuf_used_pos]!=0 && (global_cmdbuf_node[cmdbuf_used_pos] == NULL ) && (cmdbuf_node_unexpected[cmdbuf_used_pos] == 0x55))
|
||||
{
|
||||
pr_warn("vc8000e:unexpected cmdbuf_used[%d] != 0,but global_cmdbuf_node[%d] is NULL\n",
|
||||
cmdbuf_used_pos,cmdbuf_used_pos);
|
||||
cmdbuf_node_unexpected[cmdbuf_used_pos] = 0x55;
|
||||
}
|
||||
#endif
|
||||
cmdbuf_used_pos++;
|
||||
if(cmdbuf_used_pos>=TOTAL_DISCRETE_CMDBUF_NUM)
|
||||
cmdbuf_used_pos=0;
|
||||
|
||||
if(cmdbuf_used_pos_start == cmdbuf_used_pos) //searched all,not find one,should return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&vcmd_cmdbuf_alloc_lock, flags);
|
||||
pr_err("%s:vc8000e: no cmdbuf found,cmdbuf_used_residual %d\n",__func__,cmdbuf_used_residual);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1493,8 +1560,13 @@ static long reserve_cmdbuf(struct file *filp,struct exchange_parameter* input_pa
|
||||
spin_lock_irqsave(&process_manager_obj->spinlock, flags);
|
||||
process_manager_obj->total_exe_time += input_para->executing_time;
|
||||
spin_unlock_irqrestore(&process_manager_obj->spinlock, flags);
|
||||
if(wait_event_interruptible(process_manager_obj->wait_queue, wait_process_resource_rdy(process_manager_obj)))
|
||||
return -1;
|
||||
if(!wait_event_interruptible_timeout(process_manager_obj->wait_queue, wait_process_resource_rdy(process_manager_obj),
|
||||
msecs_to_jiffies(500) ))
|
||||
{
|
||||
pr_err("vc8000e: wait_process_resource_rdy timeout! total_exe_time %lld\n",process_manager_obj->total_exe_time);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
new_cmdbuf_node=create_cmdbuf_node();
|
||||
if(new_cmdbuf_node==NULL)
|
||||
@@ -1728,7 +1800,7 @@ static long link_and_run_cmdbuf(struct file *filp,struct exchange_parameter* inp
|
||||
|
||||
dev = &hantrovcmd_data[cmdbuf_obj->core_id];
|
||||
input_para->core_id = cmdbuf_obj->core_id;
|
||||
PDEBUG("Allocate cmd buffer [%d] to core [%d]\n", cmdbuf_id, input_para->core_id);
|
||||
PDEBUG("filp=%px, VCMD Link CMDBUF [%d] to core [%d]\n", (void *)filp, cmdbuf_id, input_para->core_id);
|
||||
//set ddr address for vcmd registers copy.
|
||||
if(dev->hw_version_id > HW_ID_1_0_C )
|
||||
{
|
||||
@@ -1937,7 +2009,7 @@ static unsigned int wait_cmdbuf_ready(struct file *filp,u16 cmdbuf_id,u32 *irq_s
|
||||
check_cmdbuf_irq(dev,cmdbuf_obj,irq_status_ret), msecs_to_jiffies(500) )
|
||||
)
|
||||
{
|
||||
pr_err("vcmd_wait_queue_0 timeout\n");
|
||||
pr_err("vc8000e:vcmd_wait_queue_0 timeout cmdbuf[%d]\n",cmdbuf_id);
|
||||
//abort the vcmd
|
||||
vcmd_write_register_value((const void *)dev->hwregs,dev->reg_mirror,HWIF_VCMD_START_TRIGGER,0);
|
||||
return -ETIME;
|
||||
@@ -1952,7 +2024,7 @@ bool hantrovcmd_devfreq_check_state(void)
|
||||
u32 state = 0;
|
||||
for (core_id = 0;core_id < total_vcmd_core_num; core_id++) {
|
||||
state = vcmd_get_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_WORK_STATE);
|
||||
if((state != 3) && (state != 0)) //HW state pend or idle
|
||||
if((state != 0) && (state != 3) ) //HW state pend or idle
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -2078,7 +2150,7 @@ static long hantrovcmd_ioctl(struct file *filp,
|
||||
ret = reserve_cmdbuf(filp,&input_para);
|
||||
if (ret == 0)
|
||||
copy_to_user((struct exchange_parameter*)arg,&input_para,sizeof(struct exchange_parameter));
|
||||
PDEBUG(" VCMD Reserve CMDBUF %d\n", input_para.cmdbuf_id);
|
||||
PDEBUG("filp=%px, VCMD Reserve CMDBUF [%d] remain %d \n", (void *)filp, input_para.cmdbuf_id,cmdbuf_used_residual);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2088,7 +2160,7 @@ static long hantrovcmd_ioctl(struct file *filp,
|
||||
long retVal;
|
||||
copy_from_user(&input_para,(struct exchange_parameter*)arg,sizeof(struct exchange_parameter));
|
||||
|
||||
PDEBUG("VCMD link and run cmdbuf\n");
|
||||
PDEBUG("filp=%px,VCMD link and run cmdbuf,[%d] \n",(void *)filp, input_para.cmdbuf_id);
|
||||
pm_runtime_resume_and_get(dev);
|
||||
if (process_manager_obj)
|
||||
process_manager_obj->pm_count++;
|
||||
@@ -2107,10 +2179,11 @@ static long hantrovcmd_ioctl(struct file *filp,
|
||||
__get_user(cmdbuf_id, (u16*)arg);
|
||||
/*high 16 bits are core id, low 16 bits are cmdbuf_id*/
|
||||
|
||||
PDEBUG("VCMD wait for CMDBUF finishing. \n");
|
||||
PDEBUG("filp=%px,VCMD wait for CMDBUF finishing. %d,\n",filp,cmdbuf_id);
|
||||
|
||||
//TODO
|
||||
tmp = wait_cmdbuf_ready(filp,cmdbuf_id,&irq_status_ret);
|
||||
PDEBUG("filp=%px,VCMD wait for CMDBUF finished. %d,\n",filp,cmdbuf_id);
|
||||
cmdbuf_id=(u16)irq_status_ret;
|
||||
if (tmp==0)
|
||||
{
|
||||
@@ -2130,13 +2203,12 @@ static long hantrovcmd_ioctl(struct file *filp,
|
||||
__get_user(cmdbuf_id, (u16*)arg);
|
||||
/*16 bits are cmdbuf_id*/
|
||||
|
||||
PDEBUG("VCMD release CMDBUF\n");
|
||||
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
if (process_manager_obj)
|
||||
process_manager_obj->pm_count--;
|
||||
release_cmdbuf(filp,cmdbuf_id);
|
||||
PDEBUG("filp=%px,VCMD release CMDBUF ,%d,remain %d \n",filp,cmdbuf_id,cmdbuf_used_residual);
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
@@ -2388,7 +2460,7 @@ static int hantrovcmd_open(struct inode *inode, struct file *filp)
|
||||
spin_unlock_irqrestore(&vcmd_process_manager_lock, flags);
|
||||
filp->private_data = process_manager_node->data;
|
||||
|
||||
PDEBUG("dev opened\n");
|
||||
PDEBUG("process node %px for filp opened %px\n", (void *)process_manager_node, (void *)filp);
|
||||
return result;
|
||||
}
|
||||
static int __hantrovcmd_release(struct inode *inode, struct file *filp)
|
||||
@@ -2406,9 +2478,8 @@ static int __hantrovcmd_release(struct inode *inode, struct file *filp)
|
||||
unsigned long flags;
|
||||
long retVal=0;
|
||||
|
||||
PDEBUG("dev closed for process %p\n", (void *)filp);
|
||||
if (down_interruptible(&vcmd_reserve_cmdbuf_sem[dev->vcmd_core_cfg.sub_module_type]))
|
||||
return -ERESTARTSYS;
|
||||
PDEBUG("dev closed for process %px\n", (void *)filp);
|
||||
down(&vcmd_reserve_cmdbuf_sem[dev->vcmd_core_cfg.sub_module_type]); //should be wait,do not use interruptible interface
|
||||
|
||||
for (core_id = 0;core_id < total_vcmd_core_num; core_id++)
|
||||
{
|
||||
@@ -2421,6 +2492,13 @@ static int __hantrovcmd_release(struct inode *inode, struct file *filp)
|
||||
if(new_cmdbuf_node==NULL)
|
||||
break;
|
||||
cmdbuf_obj_temp=(struct cmdbuf_obj*)new_cmdbuf_node->data;
|
||||
if(cmdbuf_obj_temp->cmdbuf_id > 1)
|
||||
{
|
||||
PDEBUG("Process %px is releasing: checking cmdbuf %d (done %d,linked %d wstat %d) process %px. remain %d\n",
|
||||
filp, cmdbuf_obj_temp->cmdbuf_id, cmdbuf_obj_temp->cmdbuf_run_done,cmdbuf_obj_temp->cmdbuf_data_linked,
|
||||
dev[core_id].working_state,
|
||||
cmdbuf_obj_temp->filp,cmdbuf_used_residual);
|
||||
}
|
||||
if (dev[core_id].hwregs && (cmdbuf_obj_temp->filp == filp))
|
||||
{
|
||||
if(cmdbuf_obj_temp->cmdbuf_run_done)
|
||||
@@ -2451,111 +2529,127 @@ static int __hantrovcmd_release(struct inode *inode, struct file *filp)
|
||||
bi_list_node* done_cmdbuf_node = NULL;
|
||||
int abort_cmdbuf_id;
|
||||
int loop_count = 0;
|
||||
u32 irq_status_ret;
|
||||
|
||||
//abort the vcmd and wait
|
||||
PDEBUG("Abort due to linked cmdbuf %d of current process.\n", cmdbuf_obj_temp->cmdbuf_id);
|
||||
#ifdef VCMD_DEBUG_INTERNAL
|
||||
printk_vcmd_register_debug((const void *)dev[core_id].hwregs, "Before trigger to 0");
|
||||
#endif
|
||||
// disable abort interrupt
|
||||
vcmd_write_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_START_TRIGGER,0);
|
||||
vcmd_aborted = 1;
|
||||
software_triger_abort = 1;
|
||||
#ifdef VCMD_DEBUG_INTERNAL
|
||||
printk_vcmd_register_debug((const void *)dev[core_id].hwregs,"After trigger to 0");
|
||||
#endif
|
||||
// wait vcmd core aborted and vcmd enters IDLE mode.
|
||||
while (vcmd_get_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_WORK_STATE)) {
|
||||
loop_count++;
|
||||
if (!(loop_count % 10)) {
|
||||
u32 irq_status = vcmd_read_reg((const void *)dev[core_id].hwregs, VCMD_REGISTER_INT_STATUS_OFFSET);
|
||||
pr_err("hantrovcmd: expected idle state, but irq status = 0x%0x\n", irq_status);
|
||||
pr_err("hantrovcmd: vcmd current status is %d\n", vcmd_get_register_value((const void *)dev[core_id].hwregs, dev[core_id].reg_mirror, HWIF_VCMD_WORK_STATE));
|
||||
}
|
||||
mdelay(10); // wait 10ms
|
||||
if (loop_count > 100) { // too long
|
||||
pr_err("hantrovcmd: too long before vcmd core to IDLE state\n");
|
||||
process_manager_obj = (struct process_manager_obj*)filp->private_data;
|
||||
if (process_manager_obj)
|
||||
{
|
||||
while(process_manager_obj->pm_count > 0)
|
||||
{
|
||||
pm_runtime_mark_last_busy(&dev[0].pdev->dev);
|
||||
pm_runtime_put_autosuspend(&dev[0].pdev->dev);
|
||||
process_manager_obj->pm_count--;
|
||||
spin_unlock_irqrestore(dev[core_id].spinlock, flags);
|
||||
if(wait_event_timeout(*dev[core_id].wait_queue,
|
||||
check_cmdbuf_irq(dev,cmdbuf_obj_temp,&irq_status_ret),msecs_to_jiffies(1000))
|
||||
)
|
||||
{
|
||||
spin_lock_irqsave(dev[core_id].spinlock, flags);
|
||||
PDEBUG(" ## wait got cmdbuf[%d] done %d \n",cmdbuf_obj_temp->cmdbuf_id,cmdbuf_obj_temp->cmdbuf_run_done);
|
||||
cmdbuf_obj_temp->cmdbuf_need_remove=1;
|
||||
retVal=release_cmdbuf_node(&dev[core_id].list_manager,new_cmdbuf_node);
|
||||
if(retVal==1)
|
||||
cmdbuf_obj_temp->process_manager_obj = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
//abort the vcmd and wait
|
||||
PDEBUG("Abort due to linked cmdbuf %d of current process.\n", cmdbuf_obj_temp->cmdbuf_id);
|
||||
#ifdef VCMD_DEBUG_INTERNAL
|
||||
printk_vcmd_register_debug((const void *)dev[core_id].hwregs, "Before trigger to 0");
|
||||
#endif
|
||||
// disable abort interrupt
|
||||
vcmd_write_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_START_TRIGGER,0);
|
||||
vcmd_aborted = 1;
|
||||
software_triger_abort = 1;
|
||||
#ifdef VCMD_DEBUG_INTERNAL
|
||||
printk_vcmd_register_debug((const void *)dev[core_id].hwregs,"After trigger to 0");
|
||||
#endif
|
||||
// wait vcmd core aborted and vcmd enters IDLE mode.
|
||||
while (vcmd_get_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_WORK_STATE)) {
|
||||
loop_count++;
|
||||
if (!(loop_count % 10)) {
|
||||
u32 irq_status = vcmd_read_reg((const void *)dev[core_id].hwregs, VCMD_REGISTER_INT_STATUS_OFFSET);
|
||||
pr_err("hantrovcmd: expected idle state, but irq status = 0x%0x\n", irq_status);
|
||||
pr_err("hantrovcmd: vcmd current status is %d\n", vcmd_get_register_value((const void *)dev[core_id].hwregs, dev[core_id].reg_mirror, HWIF_VCMD_WORK_STATE));
|
||||
}
|
||||
mdelay(10); // wait 10ms
|
||||
if (loop_count > 100) { // too long
|
||||
pr_err("hantrovcmd: too long before vcmd core to IDLE state\n");
|
||||
process_manager_obj = (struct process_manager_obj*)filp->private_data;
|
||||
if (process_manager_obj)
|
||||
{
|
||||
while(process_manager_obj->pm_count > 0)
|
||||
{
|
||||
pm_runtime_mark_last_busy(&dev[0].pdev->dev);
|
||||
pm_runtime_put_autosuspend(&dev[0].pdev->dev);
|
||||
process_manager_obj->pm_count--;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(dev[core_id].spinlock, flags);
|
||||
up(&vcmd_reserve_cmdbuf_sem[dev->vcmd_core_cfg.sub_module_type]);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(dev[core_id].spinlock, flags);
|
||||
up(&vcmd_reserve_cmdbuf_sem[dev->vcmd_core_cfg.sub_module_type]);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
}
|
||||
dev[core_id].working_state = WORKING_STATE_IDLE;
|
||||
// clear interrupt & restore abort_e
|
||||
if (vcmd_get_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_IRQ_ABORT)) {
|
||||
PDEBUG("Abort interrupt triggered, now clear it to avoid abort int...\n");
|
||||
vcmd_write_reg((const void *)dev[core_id].hwregs, VCMD_REGISTER_INT_STATUS_OFFSET, 0x1<<4);
|
||||
PDEBUG("Now irq status = 0x%0x.\n", vcmd_read_reg((const void *)dev[core_id].hwregs, VCMD_REGISTER_INT_STATUS_OFFSET));
|
||||
}
|
||||
|
||||
abort_cmdbuf_id = vcmd_get_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_CMDBUF_EXECUTING_ID);
|
||||
PDEBUG("Abort when executing cmd buf %d.\n", abort_cmdbuf_id);
|
||||
dev[core_id].sw_cmdbuf_rdy_num = 0;
|
||||
dev[core_id].duration_without_int = 0;
|
||||
vcmd_write_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_EXE_CMDBUF_COUNT,0);
|
||||
vcmd_write_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_RDY_CMDBUF_COUNT,0);
|
||||
|
||||
/* Mark cmdbuf_run_done to 1 for all the cmd buf executed. */
|
||||
done_cmdbuf_node = dev[core_id].list_manager.head;
|
||||
while (done_cmdbuf_node) {
|
||||
if (!((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_run_done) {
|
||||
((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_run_done = 1;
|
||||
((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_data_linked = 0;
|
||||
PDEBUG("Set cmdbuf [%d] cmdbuf_run_done to 1.\n", ((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_id);
|
||||
}
|
||||
if (((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_id == abort_cmdbuf_id)
|
||||
break;
|
||||
done_cmdbuf_node = done_cmdbuf_node->next;
|
||||
}
|
||||
if (cmdbuf_obj_temp->cmdbuf_run_done) {
|
||||
/* current cmdbuf is in fact has been executed, but due to interrupt is not triggered, the status is not updated.
|
||||
Just delink and remove it from the list. */
|
||||
if (done_cmdbuf_node && done_cmdbuf_node->data) {
|
||||
PDEBUG("done_cmdbuf_node is cmdbuf [%d].\n", ((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_id);
|
||||
}
|
||||
done_cmdbuf_node = done_cmdbuf_node->next;
|
||||
if (done_cmdbuf_node)
|
||||
restart_cmdbuf = (struct cmdbuf_obj*)done_cmdbuf_node->data;
|
||||
if (restart_cmdbuf) {
|
||||
PDEBUG("Set restart cmdbuf [%d] via if.\n", restart_cmdbuf->cmdbuf_id);
|
||||
}
|
||||
} else {
|
||||
last_cmdbuf_node = new_cmdbuf_node;
|
||||
/* cmd buf num from aborted cmd buf to current cmdbuf_obj_temp */
|
||||
if (cmdbuf_obj_temp->cmdbuf_id != abort_cmdbuf_id) {
|
||||
last_cmdbuf_node = new_cmdbuf_node->previous;
|
||||
|
||||
while (last_cmdbuf_node &&
|
||||
((struct cmdbuf_obj*)last_cmdbuf_node->data)->cmdbuf_id != abort_cmdbuf_id) {
|
||||
restart_cmdbuf = (struct cmdbuf_obj*)last_cmdbuf_node->data;
|
||||
last_cmdbuf_node = last_cmdbuf_node->previous;
|
||||
dev[core_id].sw_cmdbuf_rdy_num++;
|
||||
dev[core_id].duration_without_int += restart_cmdbuf->executing_time;
|
||||
PDEBUG("Keep valid cmdbuf [%d] in the list.\n", restart_cmdbuf->cmdbuf_id);
|
||||
dev[core_id].working_state = WORKING_STATE_IDLE;
|
||||
// clear interrupt & restore abort_e
|
||||
if (vcmd_get_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_IRQ_ABORT)) {
|
||||
PDEBUG("Abort interrupt triggered, now clear it to avoid abort int...\n");
|
||||
vcmd_write_reg((const void *)dev[core_id].hwregs, VCMD_REGISTER_INT_STATUS_OFFSET, 0x1<<4);
|
||||
PDEBUG("Now irq status = 0x%0x.\n", vcmd_read_reg((const void *)dev[core_id].hwregs, VCMD_REGISTER_INT_STATUS_OFFSET));
|
||||
}
|
||||
}
|
||||
if (restart_cmdbuf) {
|
||||
PDEBUG("Set restart cmdbuf [%d] via else.\n", restart_cmdbuf->cmdbuf_id);
|
||||
}
|
||||
}
|
||||
|
||||
// remove first linked cmdbuf from list
|
||||
vcmd_delink_rm_cmdbuf(&dev[core_id], new_cmdbuf_node);
|
||||
abort_cmdbuf_id = vcmd_get_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_CMDBUF_EXECUTING_ID);
|
||||
PDEBUG("Abort when executing cmd buf %d.\n", abort_cmdbuf_id);
|
||||
dev[core_id].sw_cmdbuf_rdy_num = 0;
|
||||
dev[core_id].duration_without_int = 0;
|
||||
vcmd_write_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_EXE_CMDBUF_COUNT,0);
|
||||
vcmd_write_register_value((const void *)dev[core_id].hwregs,dev[core_id].reg_mirror,HWIF_VCMD_RDY_CMDBUF_COUNT,0);
|
||||
|
||||
/* Mark cmdbuf_run_done to 1 for all the cmd buf executed. */
|
||||
done_cmdbuf_node = dev[core_id].list_manager.head;
|
||||
while (done_cmdbuf_node) {
|
||||
if (!((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_run_done) {
|
||||
((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_run_done = 1;
|
||||
((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_data_linked = 0;
|
||||
PDEBUG("Set cmdbuf [%d] cmdbuf_run_done to 1.\n", ((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_id);
|
||||
}
|
||||
if (((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_id == abort_cmdbuf_id)
|
||||
break;
|
||||
done_cmdbuf_node = done_cmdbuf_node->next;
|
||||
}
|
||||
if (cmdbuf_obj_temp->cmdbuf_run_done) {
|
||||
/* current cmdbuf is in fact has been executed, but due to interrupt is not triggered, the status is not updated.
|
||||
Just delink and remove it from the list. */
|
||||
if (done_cmdbuf_node && done_cmdbuf_node->data) {
|
||||
PDEBUG("done_cmdbuf_node is cmdbuf [%d].\n", ((struct cmdbuf_obj*)done_cmdbuf_node->data)->cmdbuf_id);
|
||||
}
|
||||
done_cmdbuf_node = done_cmdbuf_node->next;
|
||||
if (done_cmdbuf_node)
|
||||
restart_cmdbuf = (struct cmdbuf_obj*)done_cmdbuf_node->data;
|
||||
if (restart_cmdbuf) {
|
||||
PDEBUG("Set restart cmdbuf [%d] via if.\n", restart_cmdbuf->cmdbuf_id);
|
||||
}
|
||||
} else {
|
||||
last_cmdbuf_node = new_cmdbuf_node;
|
||||
/* cmd buf num from aborted cmd buf to current cmdbuf_obj_temp */
|
||||
if (cmdbuf_obj_temp->cmdbuf_id != abort_cmdbuf_id) {
|
||||
last_cmdbuf_node = new_cmdbuf_node->previous;
|
||||
|
||||
while (last_cmdbuf_node &&
|
||||
((struct cmdbuf_obj*)last_cmdbuf_node->data)->cmdbuf_id != abort_cmdbuf_id) {
|
||||
restart_cmdbuf = (struct cmdbuf_obj*)last_cmdbuf_node->data;
|
||||
last_cmdbuf_node = last_cmdbuf_node->previous;
|
||||
dev[core_id].sw_cmdbuf_rdy_num++;
|
||||
dev[core_id].duration_without_int += restart_cmdbuf->executing_time;
|
||||
PDEBUG("Keep valid cmdbuf [%d] in the list.\n", restart_cmdbuf->cmdbuf_id);
|
||||
}
|
||||
}
|
||||
if (restart_cmdbuf) {
|
||||
PDEBUG("Set restart cmdbuf [%d] via else.\n", restart_cmdbuf->cmdbuf_id);
|
||||
}
|
||||
}
|
||||
|
||||
// remove first linked cmdbuf from list
|
||||
vcmd_delink_rm_cmdbuf(&dev[core_id], new_cmdbuf_node);
|
||||
}
|
||||
|
||||
}
|
||||
software_triger_abort = 0;
|
||||
release_cmdbuf_num++;
|
||||
PDEBUG("release reserved cmdbuf\n");
|
||||
PDEBUG("vc8000e : release reserved cmdbuf,remain %d\n",cmdbuf_used_residual);
|
||||
}
|
||||
else if (vcmd_aborted && !cmdbuf_obj_temp->cmdbuf_run_done) {
|
||||
/* VCMD is aborted, need to re-calculate the duration_without_int */
|
||||
@@ -2618,7 +2712,12 @@ static int __hantrovcmd_release(struct inode *inode, struct file *filp)
|
||||
wake_up_all(dev[core_id].wait_queue);
|
||||
}
|
||||
if(release_cmdbuf_num)
|
||||
wake_up_interruptible_all(&vcmd_cmdbuf_memory_wait);
|
||||
wake_up_all(&vcmd_cmdbuf_memory_wait);
|
||||
|
||||
// free reserved but unlinkd node
|
||||
// Here is powerfull free all this process reserved/linked cmdbuf
|
||||
free_cmdbuf_not_linked_by_flip(filp);
|
||||
|
||||
spin_lock_irqsave(&vcmd_process_manager_lock, flags);
|
||||
process_manager_node = global_process_manager.head;
|
||||
while(1)
|
||||
@@ -2640,6 +2739,7 @@ static int __hantrovcmd_release(struct inode *inode, struct file *filp)
|
||||
}
|
||||
}
|
||||
//remove node from list
|
||||
PDEBUG("process node %px for filp to be removed: %px remain %d\n", (void *)process_manager_node, (void *)process_manager_obj->filp,cmdbuf_used_residual);
|
||||
bi_list_remove_node(&global_process_manager,process_manager_node);
|
||||
spin_unlock_irqrestore(&vcmd_process_manager_lock, flags);
|
||||
free_process_manager_node(process_manager_node);
|
||||
@@ -2790,7 +2890,7 @@ static u32 ConfigAXIFE(u32 mode)
|
||||
#endif
|
||||
if (axife_hwregs[i][0] != NULL)
|
||||
{
|
||||
PDEBUG("ConfigAXIFE: axife_hwregs[%d][0]=%p\n", i, axife_hwregs[i][0]);
|
||||
PDEBUG("ConfigAXIFE: axife_hwregs[%d][0]=%px\n", i, axife_hwregs[i][0]);
|
||||
AXIFEEnable(axife_hwregs[i][0], mode);
|
||||
}
|
||||
}
|
||||
@@ -2810,7 +2910,7 @@ static u32 ConfigAXIFE(u32 mode)
|
||||
#endif
|
||||
if (axife_hwregs[i][1] != NULL)
|
||||
{
|
||||
PDEBUG("ConfigAXIFE: axife_hwregs[%d][1]=%p\n", i, axife_hwregs[i][1]);
|
||||
PDEBUG("ConfigAXIFE: axife_hwregs[%d][1]=%px\n", i, axife_hwregs[i][1]);
|
||||
AXIFEEnable(axife_hwregs[i][1] , mode);
|
||||
}
|
||||
}
|
||||
@@ -2858,7 +2958,7 @@ static u32 ConfigMMU(void)
|
||||
}
|
||||
else
|
||||
pr_info("MMU detected!\n");
|
||||
PDEBUG("mmu_hwregs[%d][0]=%p\n", i, mmu_hwregs[i][0]);
|
||||
PDEBUG("mmu_hwregs[%d][0]=%px\n", i, mmu_hwregs[i][0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2876,7 +2976,7 @@ static u32 ConfigMMU(void)
|
||||
mmu_hwregs[i][1] = (volatile u8*)ioremap(vcmd_core_array[i].vcmd_base_addr
|
||||
+vcmd_core_array[i].submodule_MMU_addr[1], MMU_SIZE);
|
||||
#endif
|
||||
PDEBUG("mmu_hwregs[%d][1]=%p\n", i, mmu_hwregs[i][1]);
|
||||
PDEBUG("mmu_hwregs[%d][1]=%px\n", i, mmu_hwregs[i][1]);
|
||||
}
|
||||
}
|
||||
mmu_status = MMUEnable(mmu_hwregs);
|
||||
@@ -3492,7 +3592,8 @@ static void read_main_module_all_registers(u32 main_module_type)
|
||||
//msleep(1000);
|
||||
hantrovcmd_isr(input_para.core_id, &hantrovcmd_data[input_para.core_id]);
|
||||
wait_cmdbuf_ready(NULL,input_para.cmdbuf_id,&irq_status_ret);
|
||||
encoder_devfreq_record_idle( encoder_get_devfreq_priv_data() );
|
||||
|
||||
pr_info("%s:record_idle:busy_count = %d\n",__func__,encoder_get_devfreq_priv_data()->busy_count);
|
||||
status_base_virt_addr=vcmd_status_buf_mem_pool.virtualAddress + input_para.cmdbuf_id*CMDBUF_MAX_SIZE/4+(vcmd_manager[input_para.module_type][0]->vcmd_core_cfg.submodule_main_addr/2/4+0);
|
||||
pr_info("vc8000_vcmd_driver: main module register 0:0x%x\n",*status_base_virt_addr);
|
||||
pr_info("vc8000_vcmd_driver: main module register 80:0x%x\n",*(status_base_virt_addr+80));
|
||||
@@ -3869,7 +3970,7 @@ void encoder_devfreq_record_busy(struct encoder_devfreq *devfreq)
|
||||
encoder_dev_clk_lock();
|
||||
spin_lock_irqsave(&devfreq->lock, irqflags);
|
||||
busy_count = devfreq->busy_count;
|
||||
//pr_info("record_busy:busy_count = %d\n",busy_count);
|
||||
PDEBUG("record_busy:busy_count = %d\n",busy_count);
|
||||
if(devfreq->busy_count > 0)
|
||||
{
|
||||
devfreq->busy_count++;
|
||||
@@ -3898,7 +3999,7 @@ void encoder_devfreq_record_idle(struct encoder_devfreq *devfreq)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&devfreq->lock, irqflags);
|
||||
//pr_info("record_idle:busy_count = %d\n",devfreq->busy_count);
|
||||
PDEBUG("record_idle:busy_count = %d\n",devfreq->busy_count);
|
||||
if(devfreq->busy_count > 1)
|
||||
{
|
||||
devfreq->busy_count--;
|
||||
@@ -4102,7 +4203,7 @@ int encoder_devfreq_init(struct device *dev)
|
||||
int ret = 0;
|
||||
struct encoder_devfreq *devfreq = encoder_get_devfreq_priv_data();
|
||||
|
||||
memset(devfreq,sizeof(struct encoder_devfreq),0);
|
||||
memset(devfreq,0,sizeof(struct encoder_devfreq));
|
||||
spin_lock_init(&devfreq->lock);
|
||||
init_waitqueue_head(&devfreq->target_freq_wait_queue);
|
||||
mutex_init(&devfreq->clk_mutex);
|
||||
@@ -4486,6 +4587,7 @@ int __init hantroenc_vcmd_probe(struct platform_device *pdev)
|
||||
cmdbuf_used_pos=1;
|
||||
cmdbuf_used[0]=1;
|
||||
cmdbuf_used_residual -=1;
|
||||
pr_info(" CMDBUF[0] reserved,remain %d\n",cmdbuf_used_residual);
|
||||
|
||||
pr_info("vc8000_vcmd_driver: module inserted. Major <%d>\n", hantrovcmd_major);
|
||||
|
||||
@@ -4699,7 +4801,7 @@ static int vcmd_reserve_IO(void)
|
||||
|
||||
/*read hwid and check validness and store it*/
|
||||
hwid = (u32)ioread32(( void *)hantrovcmd_data[i].hwregs);
|
||||
pr_info("vcmd_reserve_IO: hantrovcmd_data[%d].hwregs=0x%p\n",i, hantrovcmd_data[i].hwregs);
|
||||
pr_info("vcmd_reserve_IO: hantrovcmd_data[%d].hwregs=0x%px\n",i, hantrovcmd_data[i].hwregs);
|
||||
pr_info("hwid=0x%08x\n", hwid);
|
||||
hantrovcmd_data[i].hw_version_id = hwid;
|
||||
|
||||
@@ -4879,7 +4981,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id)
|
||||
new_cmdbuf_node = global_cmdbuf_node[cmdbuf_id];
|
||||
if(new_cmdbuf_node==NULL)
|
||||
{
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id !!\n");
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id %d line %d!!\n",cmdbuf_id,__LINE__);
|
||||
spin_unlock_irqrestore(dev->spinlock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -4951,7 +5053,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id)
|
||||
new_cmdbuf_node = global_cmdbuf_node[cmdbuf_id];
|
||||
if(new_cmdbuf_node==NULL)
|
||||
{
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id !!\n");
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id %d line %d!!\n",cmdbuf_id,__LINE__);
|
||||
spin_unlock_irqrestore(dev->spinlock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -5023,7 +5125,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id)
|
||||
new_cmdbuf_node = global_cmdbuf_node[cmdbuf_id];
|
||||
if(new_cmdbuf_node==NULL)
|
||||
{
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id !!\n");
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id %d line %d!!\n",cmdbuf_id,__LINE__);
|
||||
spin_unlock_irqrestore(dev->spinlock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -5163,7 +5265,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id)
|
||||
new_cmdbuf_node = global_cmdbuf_node[cmdbuf_id];
|
||||
if(new_cmdbuf_node==NULL)
|
||||
{
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id !!\n");
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id %d line %d!!\n",cmdbuf_id,__LINE__);
|
||||
spin_unlock_irqrestore(dev->spinlock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -5233,7 +5335,7 @@ static irqreturn_t hantrovcmd_isr(int irq, void *dev_id)
|
||||
new_cmdbuf_node = global_cmdbuf_node[cmdbuf_id];
|
||||
if(new_cmdbuf_node==NULL)
|
||||
{
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id !!\n");
|
||||
pr_err("hantrovcmd_isr error cmdbuf_id %d line %d!!\n",cmdbuf_id,__LINE__);
|
||||
spin_unlock_irqrestore(dev->spinlock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
59
drivers/usb/dwc3/dwc3-thead.c
Normal file → Executable file
59
drivers/usb/dwc3/dwc3-thead.c
Normal file → Executable file
@@ -259,40 +259,12 @@ static int dwc3_thead_remove(struct platform_device *pdev)
|
||||
static int dwc3_thead_pm_suspend(struct device *dev)
|
||||
{
|
||||
struct dwc3_thead *thead = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
dwc3_thead_assert(thead);
|
||||
|
||||
if (!IS_ERR(thead->hubswitch)) {
|
||||
ret = regulator_disable(thead->hub1v2);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to disable regulator hub1v2 %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
if (!IS_ERR(thead->hub5v)) {
|
||||
ret = regulator_disable(thead->hub5v);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to disable regulator hub1v2 %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
clk_bulk_disable(thead->num_clocks, thead->clks);
|
||||
ret = regulator_disable(thead->vbus);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to disable regulator vbus %d\n", ret);
|
||||
}
|
||||
ret = regulator_disable(thead->hub1v2);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to disable regulator hub1v2 %d\n", ret);
|
||||
}
|
||||
ret = regulator_disable(thead->hub5v);
|
||||
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to disable regulator hub1v2 %d\n", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -300,35 +272,6 @@ static int dwc3_thead_pm_resume(struct device *dev)
|
||||
{
|
||||
struct dwc3_thead *thead = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
dev_info(dev,"%s\n",__func__);
|
||||
ret = regulator_enable(thead->vbus);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable regulator vbus %d\n", ret);
|
||||
}
|
||||
ret = regulator_enable(thead->hub1v2);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable regulator hub1v2 %d\n", ret);
|
||||
}
|
||||
ret = regulator_enable(thead->hub5v);
|
||||
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable regulator hub1v2 %d\n", ret);
|
||||
}
|
||||
|
||||
/* enable regulator here for some extend regulator does not have pm func */
|
||||
if (!IS_ERR(thead->hub1v2)) {
|
||||
ret = regulator_enable(thead->hub1v2);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable regulator hub1v2 %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
if (!IS_ERR(thead->hub5v)) {
|
||||
ret = regulator_enable(thead->hub5v);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable regulator hub1v2 %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
ret = clk_bulk_prepare_enable(thead->num_clocks, thead->clks);
|
||||
if (ret) {
|
||||
|
||||
@@ -86,6 +86,7 @@
|
||||
#include "video_memory.h"
|
||||
#include "rsvmem_pool.h"
|
||||
|
||||
|
||||
//#define VIDMEM_DMA_MAP
|
||||
#define DISCRETE_PAGES 0
|
||||
//#define VIDMEM_DEBUG
|
||||
@@ -183,6 +184,7 @@
|
||||
#ifndef VIDMEM_DEBUG
|
||||
#define DEBUG_PRINT(...) \
|
||||
do { \
|
||||
pr_debug(__VA_ARGS__);\
|
||||
} while (0)
|
||||
#else
|
||||
#undef DEBUG_PRINT
|
||||
@@ -202,8 +204,9 @@ struct mem_block
|
||||
struct vm_area_struct * vma;
|
||||
bool is_cma;
|
||||
bool is_vi_mem;
|
||||
bool cache_en;
|
||||
void *va;
|
||||
|
||||
struct file *filp;
|
||||
union
|
||||
{
|
||||
/* Pointer to a array of pages. */
|
||||
@@ -232,6 +235,7 @@ struct mem_node
|
||||
struct mem_block memBlk;
|
||||
unsigned long busAddr;
|
||||
int isImported;
|
||||
int isExported;
|
||||
struct list_head link;
|
||||
};
|
||||
|
||||
@@ -243,6 +247,9 @@ struct file_node
|
||||
};
|
||||
|
||||
static struct list_head fileList;
|
||||
/* golbal list for exported mem_node */
|
||||
static struct list_head export_list;
|
||||
static DEFINE_SPINLOCK(export_mem_lock);
|
||||
|
||||
static int vidalloc_major = 0;
|
||||
static int vidalloc_minor = 0;
|
||||
@@ -259,6 +266,7 @@ getPhysical(
|
||||
IN unsigned int Offset,
|
||||
OUT unsigned long * Physical
|
||||
);
|
||||
void free_memblk_pages(struct mem_block *memBlk);
|
||||
|
||||
static struct file_node * find_and_delete_file_node(struct file *filp)
|
||||
{
|
||||
@@ -298,6 +306,23 @@ static struct file_node * get_file_node(struct file *filp)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct mem_node * get_export_mem_node(struct file *filp, unsigned long bus_address)
|
||||
{
|
||||
struct mem_node *node;
|
||||
spin_lock(&export_mem_lock);
|
||||
list_for_each_entry(node, &export_list, link)
|
||||
{
|
||||
if (node->busAddr == bus_address)
|
||||
{
|
||||
DEBUG_PRINT("[vidmem] Found export mem node %px, %d pages\n", node);
|
||||
spin_unlock(&export_mem_lock);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
spin_unlock(&export_mem_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct mem_node * get_mem_node(struct file *filp, unsigned long bus_address, int imported)
|
||||
{
|
||||
struct file_node *fnode;
|
||||
@@ -320,6 +345,7 @@ static struct mem_node * get_mem_node(struct file *filp, unsigned long bus_addre
|
||||
}
|
||||
spin_unlock(&mem_lock);
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -441,6 +467,46 @@ OnError:
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static void invalid_data_cache(IN struct file *filp, IN unsigned long bus_address )
|
||||
{
|
||||
struct mem_block *memBlk = NULL;
|
||||
struct mem_node *mnode = NULL;
|
||||
mnode = get_mem_node(filp, bus_address, 0);
|
||||
if (NULL == mnode)
|
||||
{
|
||||
mnode = get_export_mem_node(filp, bus_address);
|
||||
if (NULL == mnode)
|
||||
return;
|
||||
}
|
||||
|
||||
memBlk = &mnode->memBlk;
|
||||
dma_addr_t dma_handle = memBlk->dma_addr;
|
||||
size_t size = memBlk->size;
|
||||
dma_sync_single_for_cpu(gdev,dma_handle ,memBlk->size,DMA_FROM_DEVICE);
|
||||
|
||||
}
|
||||
|
||||
static void flush_data_cache(IN struct file *filp, IN unsigned long bus_address )
|
||||
{
|
||||
struct mem_block *memBlk = NULL;
|
||||
struct mem_node *mnode = NULL;
|
||||
|
||||
mnode = get_mem_node(filp, bus_address, 0);
|
||||
if (NULL == mnode)
|
||||
{
|
||||
mnode = get_export_mem_node(filp, bus_address);
|
||||
if (NULL == mnode)
|
||||
return;
|
||||
}
|
||||
|
||||
memBlk = &mnode->memBlk;
|
||||
dma_addr_t dma_handle = memBlk->dma_addr;
|
||||
size_t size = memBlk->size;
|
||||
dma_sync_single_for_device(gdev,dma_handle ,memBlk->size,DMA_TO_DEVICE);
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
Mmap(
|
||||
IN struct mem_block *MemBlk,
|
||||
@@ -455,16 +521,21 @@ Mmap(
|
||||
vma->vm_flags |= VM_FLAGS;
|
||||
|
||||
/* Make this mapping write combined. */
|
||||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||
|
||||
if (!memBlk->cache_en) {
|
||||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||
}
|
||||
DEBUG_PRINT("vm_page_prot:0x%llx\n",vma->vm_page_prot);
|
||||
/* Now map all the vmalloc pages to this user address. */
|
||||
if (memBlk->contiguous)
|
||||
{
|
||||
/* map kernel memory to user space.. */
|
||||
#if 0
|
||||
if (memBlk->is_cma == true) {
|
||||
return dma_mmap_coherent(gdev, vma, memBlk->va,
|
||||
memBlk->dma_addr, vma->vm_end - vma->vm_start);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (remap_pfn_range(vma,
|
||||
vma->vm_start,
|
||||
page_to_pfn(memBlk->contiguousPages) + skipPages,
|
||||
@@ -658,6 +729,29 @@ OnError:
|
||||
|
||||
static void _dmabuf_release(struct dma_buf *dmabuf)
|
||||
{
|
||||
struct mem_block *memBlk = dmabuf->priv;
|
||||
unsigned long physical;
|
||||
//struct mem_node *mnode = (mem_node *)memBlk;
|
||||
struct mem_node *mnode = container_of(memBlk,struct mem_node,memBlk);
|
||||
if (!memBlk)
|
||||
return;
|
||||
if(!memBlk->filp)
|
||||
{
|
||||
DEBUG_PRINT("[vidmem] %s, %d: memBlk filp null\n", __func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
getPhysical(memBlk, 0, &physical);
|
||||
DEBUG_PRINT("[vidmem] %s, %d: free physical %llx,mnode %px\n", __func__, __LINE__,physical,mnode);
|
||||
|
||||
free_memblk_pages(memBlk);
|
||||
DEBUG_PRINT(" %s: remove node\n",__func__);
|
||||
//remove node from export gloabl list
|
||||
spin_lock(&export_mem_lock);
|
||||
list_del(&mnode->link);
|
||||
spin_unlock(&export_mem_lock);
|
||||
DEBUG_PRINT(" %s: FreeMemory of node\n",__func__);
|
||||
FreeMemory(mnode);
|
||||
dmabuf->priv = NULL;
|
||||
}
|
||||
|
||||
static void *_dmabuf_kmap(struct dma_buf *dmabuf, unsigned long offset)
|
||||
@@ -706,6 +800,8 @@ DMABUF_Export(
|
||||
}
|
||||
|
||||
memBlk = &mnode->memBlk;
|
||||
memBlk->filp = filp;
|
||||
mnode->isExported = 1;
|
||||
|
||||
dmabuf = memBlk->dmabuf;
|
||||
if (dmabuf == NULL)
|
||||
@@ -739,8 +835,18 @@ DMABUF_Export(
|
||||
}
|
||||
|
||||
*FD = fd;
|
||||
DEBUG_PRINT(" [vidmem] Export as fd %d,mnode %px memBlk %px\n", fd,mnode,&mnode->memBlk);
|
||||
}
|
||||
|
||||
/*exported buffer remove from list*/
|
||||
spin_lock(&mem_lock);
|
||||
list_del(&mnode->link);
|
||||
spin_unlock(&mem_lock);
|
||||
|
||||
/* add to export gloabl list*/
|
||||
spin_lock(&export_mem_lock);
|
||||
list_add_tail(&mnode->link,&export_list);
|
||||
spin_unlock(&export_mem_lock);
|
||||
OnError:
|
||||
return status;
|
||||
}
|
||||
@@ -775,7 +881,7 @@ DMABUF_Import(
|
||||
}
|
||||
|
||||
memBlk = &mnode->memBlk;
|
||||
|
||||
memBlk->filp = filp;
|
||||
/* Import dma buf handle. */
|
||||
memBlk->dmabuf = dma_buf_get(FD);
|
||||
if (!memBlk->dmabuf)
|
||||
@@ -815,7 +921,7 @@ DMABUF_Release(
|
||||
{
|
||||
struct mem_block *memBlk = NULL;
|
||||
struct mem_node *mnode = NULL;
|
||||
|
||||
DEBUG_PRINT("[vidmem] enter %s: bus_address 0x%lx\n",__func__, bus_address);
|
||||
mnode = get_mem_node(filp, bus_address, 1);
|
||||
if (NULL == mnode)
|
||||
{
|
||||
@@ -832,6 +938,7 @@ DMABUF_Release(
|
||||
|
||||
FreeMemory(memBlk->pagearray);
|
||||
|
||||
DEBUG_PRINT("[vidmem] release bus address at 0x%lx in size of %ld\n", bus_address, memBlk->size);
|
||||
spin_lock(&mem_lock);
|
||||
list_del(&mnode->link);
|
||||
spin_unlock(&mem_lock);
|
||||
@@ -991,6 +1098,13 @@ GFP_Alloc(
|
||||
gfp |= __GFP_DMA32;
|
||||
}
|
||||
|
||||
|
||||
if (Flags & ALLOC_FLAG_ENABLE_CACHE) {
|
||||
memBlk->cache_en = true;
|
||||
} else {
|
||||
memBlk->cache_en = false;
|
||||
}
|
||||
|
||||
memBlk->contiguous = contiguous;
|
||||
memBlk->numPages = numPages;
|
||||
memBlk->size = size;
|
||||
@@ -1133,7 +1247,9 @@ OnDone:
|
||||
*bus_address = physical;
|
||||
mnode->busAddr = physical;
|
||||
mnode->isImported = 0;
|
||||
spin_lock(&mem_lock);
|
||||
list_add_tail(&mnode->link, &fnode->memList);
|
||||
spin_unlock(&mem_lock);
|
||||
|
||||
DEBUG_PRINT("[vidmem] Allocated %d bytes (%ld pages) at physical address 0x%lx with %d sg table entries\n",
|
||||
size, numPages, physical, contiguous ? 1 : memBlk->sgt->nents);
|
||||
@@ -1154,27 +1270,11 @@ OnError:
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GFP_Free(
|
||||
IN struct file *filp,
|
||||
IN unsigned long bus_address
|
||||
)
|
||||
void free_memblk_pages(struct mem_block *memBlk)
|
||||
{
|
||||
size_t i;
|
||||
struct page * page;
|
||||
struct mem_block *memBlk = NULL;
|
||||
struct mem_node *mnode = NULL;
|
||||
|
||||
mnode = get_mem_node(filp, bus_address, 0);
|
||||
if (NULL == mnode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
memBlk = &mnode->memBlk;
|
||||
|
||||
DEBUG_PRINT("[vidmem] Free %ld pages from physical address 0x%lx\n", memBlk->numPages, mnode->busAddr);
|
||||
DEBUG_PRINT(" ##[vidmem] Free %ld pages, contiguous %d\n", memBlk->numPages, memBlk->contiguous);
|
||||
|
||||
if (memBlk->contiguous)
|
||||
{
|
||||
@@ -1235,6 +1335,27 @@ GFP_Free(
|
||||
{
|
||||
NonContiguousFree(memBlk->nonContiguousPages, memBlk->numPages);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GFP_Free(
|
||||
IN struct file *filp,
|
||||
IN unsigned long bus_address
|
||||
)
|
||||
{
|
||||
struct mem_block *memBlk = NULL;
|
||||
struct mem_node *mnode = NULL;
|
||||
|
||||
mnode = get_mem_node(filp, bus_address, 0);
|
||||
if (NULL == mnode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
memBlk = &mnode->memBlk;
|
||||
DEBUG_PRINT("[vidmem] Free %ld pages from physical address 0x%lx\n", memBlk->numPages, mnode->busAddr);
|
||||
|
||||
free_memblk_pages(memBlk);
|
||||
|
||||
spin_lock(&mem_lock);
|
||||
list_del(&mnode->link);
|
||||
@@ -1256,7 +1377,9 @@ GFP_MapUser(
|
||||
mnode = get_mem_node(filp, bus_address, 0);
|
||||
if (NULL == mnode)
|
||||
{
|
||||
return EINVAL;
|
||||
mnode = get_export_mem_node(filp, bus_address);
|
||||
if (NULL == mnode)
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
memBlk = &mnode->memBlk;
|
||||
@@ -1349,6 +1472,21 @@ static long vidalloc_ioctl(struct file *filp, unsigned int cmd, unsigned long ar
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MEMORY_IOC_DMABUF_FLUSH_CACHE:
|
||||
ret = copy_from_user(¶ms, (void*)arg, sizeof(VidmemParams));
|
||||
if (!ret)
|
||||
{
|
||||
flush_data_cache(filp, params.bus_address);
|
||||
}
|
||||
break;
|
||||
case MEMORY_IOC_DMABUF_INVALID_CACHE:
|
||||
ret = copy_from_user(¶ms, (void*)arg, sizeof(VidmemParams));
|
||||
if (!ret)
|
||||
{
|
||||
invalid_data_cache(filp, params.bus_address);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = EINVAL;
|
||||
}
|
||||
@@ -1385,7 +1523,11 @@ static int vidalloc_release(struct inode *inode, struct file *filp)
|
||||
list_for_each_entry_safe(node, temp, &fnode->memList, link)
|
||||
{
|
||||
// this is not expected, memory leak detected!
|
||||
pr_debug("vidmem: Found unfreed memory at 0x%lx, isImported = %d\n", node->busAddr, node->isImported);
|
||||
pr_debug("vidmem: Found unfreed memory at 0x%lx, isImported = %d isExported = %d\n", node->busAddr, node->isImported,node->isExported);
|
||||
if (node->isExported) //let dmabuf release ops free
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (node->isImported)
|
||||
DMABUF_Release(filp, node->busAddr);
|
||||
else
|
||||
@@ -1415,10 +1557,11 @@ int vidalloc_probe(struct platform_device *pdev)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
DEBUG_PRINT("enter %s\n",__func__);
|
||||
pr_info("enter %s,ver:1.2A\n",__func__);
|
||||
#if 1
|
||||
gdev = &pdev->dev;
|
||||
INIT_LIST_HEAD(&fileList);
|
||||
INIT_LIST_HEAD(&export_list);
|
||||
|
||||
result = rsvmem_pool_create(&pdev->dev);
|
||||
if (result && result != -ENODEV)
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
#define ALLOC_FLAG_CMA 0x00000008
|
||||
/* Use VI reserved memory */
|
||||
#define ALLOC_FLAG_VI 0x00000010
|
||||
/* Buffer enable cache */
|
||||
#define ALLOC_FLAG_ENABLE_CACHE 0x00000020
|
||||
|
||||
/* Alloc rsvmem pool region id should be 0~15 */
|
||||
#define SET_ALLOC_FLAG_REGION(flag, region_id) (flag & 0x00ffffff) | (region_id << 24)
|
||||
@@ -49,7 +51,9 @@
|
||||
#define MEMORY_IOC_DMABUF_EXPORT _IOWR(MEMORY_IOC_MAGIC, 3, VidmemParams *)
|
||||
#define MEMORY_IOC_DMABUF_IMPORT _IOWR(MEMORY_IOC_MAGIC, 4, VidmemParams *)
|
||||
#define MEMORY_IOC_DMABUF_RELEASE _IOWR(MEMORY_IOC_MAGIC, 5, VidmemParams *)
|
||||
#define MEMORY_IOC_MAXNR 5
|
||||
#define MEMORY_IOC_DMABUF_FLUSH_CACHE _IOWR(MEMORY_IOC_MAGIC, 6, VidmemParams *)
|
||||
#define MEMORY_IOC_DMABUF_INVALID_CACHE _IOWR(MEMORY_IOC_MAGIC, 7, VidmemParams *)
|
||||
#define MEMORY_IOC_MAXNR 7
|
||||
|
||||
typedef struct {
|
||||
unsigned long bus_address;
|
||||
@@ -59,4 +63,7 @@ typedef struct {
|
||||
int flags;
|
||||
} VidmemParams;
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __VIDEO_MEMORY_H_ */
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "video_memory.h"
|
||||
#include "video_mem.h"
|
||||
|
||||
|
||||
#define VMEM_PRINT(level, ...) \
|
||||
{ \
|
||||
if (log_level >= VMEM_LOG_##level) \
|
||||
@@ -115,7 +114,7 @@ VMEM_allocate(void *vmem, VmemParams *params)
|
||||
}
|
||||
|
||||
params->phy_address = p.bus_address;
|
||||
VMEM_LOGI("Allocated %d bytes, phy addr 0x%08x\n",
|
||||
VMEM_LOGI("Allocated %d bytes, phy addr 0x%lx\n",
|
||||
params->size, params->phy_address);
|
||||
|
||||
return VMEM_STATUS_OK;
|
||||
@@ -129,7 +128,7 @@ VMEM_mmap(void *vmem, VmemParams *params)
|
||||
|
||||
if (vmem == NULL || params == NULL)
|
||||
return VMEM_STATUS_ERROR;
|
||||
|
||||
|
||||
if (params->vir_address != NULL)
|
||||
return VMEM_STATUS_OK;
|
||||
|
||||
@@ -140,13 +139,13 @@ VMEM_mmap(void *vmem, VmemParams *params)
|
||||
MAP_SHARED, fd, offset);
|
||||
if (vir_addr == MAP_FAILED)
|
||||
{
|
||||
VMEM_LOGE("Failed to mmap physical address: 0x%08x, using fd %d\n",
|
||||
VMEM_LOGE("Failed to mmap physical address: 0x%lx, using fd %d\n",
|
||||
params->phy_address, fd);
|
||||
return VMEM_STATUS_ERROR;
|
||||
}
|
||||
|
||||
params->vir_address = vir_addr;
|
||||
VMEM_LOGI("Mapped phy addr 0x%08x to vir addr %p, size %d\n",
|
||||
VMEM_LOGI("Mapped phy addr 0x%lx to vir addr %p, size %d\n",
|
||||
params->phy_address, params->vir_address, params->size);
|
||||
|
||||
return VMEM_STATUS_OK;
|
||||
@@ -163,7 +162,7 @@ VMEM_free(void *vmem, VmemParams *params)
|
||||
|
||||
ctx = (VmemContext *)vmem;
|
||||
|
||||
VMEM_LOGI("Free virt addr %p, phy addr 0x%08x, size %d\n",
|
||||
VMEM_LOGI("Free virt addr %p, phy addr 0x%lx, size %d\n",
|
||||
params->vir_address, params->phy_address, params->size);
|
||||
if (params->vir_address != MAP_FAILED && params->vir_address != NULL)
|
||||
munmap(params->vir_address, params->size);
|
||||
@@ -188,7 +187,7 @@ VMEM_destroy(void *vmem)
|
||||
VmemContext *ctx = (VmemContext *)vmem;
|
||||
if (ctx->fd_alloc != -1)
|
||||
close(ctx->fd_alloc);
|
||||
|
||||
|
||||
free(vmem);
|
||||
}
|
||||
|
||||
@@ -215,7 +214,7 @@ VMEM_export(void *vmem, VmemParams *params)
|
||||
}
|
||||
|
||||
params->fd = p.fd;
|
||||
VMEM_LOGI("Exported phy addr 0x%08x to fd %d, size %d\n",
|
||||
VMEM_LOGI("Exported phy addr 0x%lx to fd %d, size %d\n",
|
||||
params->phy_address, params->fd, params->size);
|
||||
|
||||
return VMEM_STATUS_OK;
|
||||
@@ -241,7 +240,7 @@ VMEM_import(void *vmem, VmemParams *params)
|
||||
|
||||
params->phy_address = p.bus_address;
|
||||
params->size = p.size;
|
||||
VMEM_LOGI("Imported fd %d to phy addr 0x%08x, size %d\n",
|
||||
VMEM_LOGI("Imported fd %d to phy addr 0x%lx, size %d\n",
|
||||
params->fd, params->phy_address, params->size);
|
||||
|
||||
return VMEM_STATUS_OK;
|
||||
@@ -256,7 +255,7 @@ VMEM_release(void *vmem, VmemParams *params)
|
||||
return VMEM_STATUS_ERROR;
|
||||
ctx = (VmemContext *)vmem;
|
||||
|
||||
VMEM_LOGI("Released imported phy addr 0x%08x, fd %d, size %d\n",
|
||||
VMEM_LOGI("Released imported phy addr 0x%lx, fd %d, size %d\n",
|
||||
params->phy_address, params->fd, params->size);
|
||||
if (params->vir_address != MAP_FAILED && params->vir_address != NULL)
|
||||
munmap(params->vir_address, params->size);
|
||||
@@ -273,6 +272,49 @@ VMEM_release(void *vmem, VmemParams *params)
|
||||
return VMEM_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
VmemStatus
|
||||
VMEM_flush_cache(void *vmem, VmemParams *params,VmemCacheDir dir)
|
||||
{
|
||||
VmemContext *ctx = NULL;
|
||||
VidmemParams p;
|
||||
int ret;
|
||||
if (vmem == NULL || params == NULL)
|
||||
return VMEM_STATUS_ERROR;
|
||||
|
||||
ctx = (VmemContext *)vmem;
|
||||
|
||||
VMEM_LOGI("Flush phy addr 0x%lx, size %d,dir:%d\n",
|
||||
params->phy_address, params->size,dir);
|
||||
|
||||
if (params->phy_address != 0)
|
||||
{
|
||||
memset(&p, 0, sizeof(p));
|
||||
p.bus_address = params->phy_address;
|
||||
if(dir == VEME_CACHE_DIR_TO_DEV)
|
||||
{
|
||||
ret = ioctl(ctx->fd_alloc, MEMORY_IOC_DMABUF_FLUSH_CACHE, &p);
|
||||
}else if(dir == VEME_CACHE_DIR_FROM_DEV)
|
||||
{
|
||||
ret = ioctl(ctx->fd_alloc, MEMORY_IOC_DMABUF_INVALID_CACHE, &p);
|
||||
}
|
||||
else
|
||||
{
|
||||
return VMEM_STATUS_ERROR;
|
||||
}
|
||||
|
||||
if(ret)
|
||||
{
|
||||
VMEM_LOGE("fail ret %d\n",ret);
|
||||
return VMEM_STATUS_ERROR;
|
||||
}
|
||||
return VMEM_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
return VMEM_STATUS_ERROR;
|
||||
}
|
||||
|
||||
static int getLogLevel()
|
||||
{
|
||||
char *env = getenv("VMEM_LOG_LEVEL");
|
||||
|
||||
@@ -34,11 +34,16 @@ extern "C" {
|
||||
#define VMEM_FLAG_CMA 0x00000008
|
||||
/* Use VI reserved memory */
|
||||
#define VMEM_FLAG_VI 0x00000010
|
||||
/* Buffer enable cache */
|
||||
#define VMEM_FLAG_ENABLE_CACHE 0x00000020
|
||||
|
||||
/* Alloc rsvmem pool region id should be 0~15 */
|
||||
#define MAX_REGION_ID 15
|
||||
|
||||
#define SET_ALLOC_FLAG_REGION(flag, region_id) (flag & 0x00ffffff) | (region_id << 24)
|
||||
#define GET_ALLOC_FLAG_REGION(flag) (flag >> 24)
|
||||
|
||||
|
||||
typedef enum _VmemStatus
|
||||
{
|
||||
VMEM_STATUS_OK = 0,
|
||||
@@ -50,11 +55,17 @@ typedef struct _VmemParams
|
||||
{
|
||||
int size;
|
||||
int flags;
|
||||
unsigned int phy_address;
|
||||
unsigned long phy_address;
|
||||
void *vir_address;
|
||||
int fd;
|
||||
} VmemParams;
|
||||
|
||||
typedef enum{
|
||||
VEME_CACHE_DIR_TO_DEV = 0,
|
||||
VEME_CACHE_DIR_FROM_DEV,
|
||||
VEME_CACHE_DIR_INVALID,
|
||||
}VmemCacheDir;
|
||||
|
||||
VmemStatus VMEM_create(void **vmem);
|
||||
VmemStatus VMEM_allocate(void *vmem, VmemParams *params);
|
||||
VmemStatus VMEM_mmap(void *vmem, VmemParams *params);
|
||||
@@ -65,6 +76,8 @@ VmemStatus VMEM_export(void *vmem, VmemParams *params);
|
||||
VmemStatus VMEM_import(void *vmem, VmemParams *params);
|
||||
VmemStatus VMEM_release(void *vmem, VmemParams *params);
|
||||
|
||||
VmemStatus VMEM_flush_cache(void *vmem, VmemParams *params,VmemCacheDir dir);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -120,20 +120,20 @@ int main(int argc, char **argv)
|
||||
}
|
||||
if (VMEM_mmap(vmem, params) != VMEM_STATUS_OK)
|
||||
{
|
||||
printf("ERROR: Failed to mmap busAddress: 0x%08x\n",
|
||||
printf("ERROR: Failed to mmap busAddress: 0x%lx\n",
|
||||
params->phy_address);
|
||||
err = 1;
|
||||
break;
|
||||
}
|
||||
if (VMEM_export(vmem, params) != VMEM_STATUS_OK)
|
||||
{
|
||||
printf("ERROR: Failed to export buffer: 0x%08x\n",
|
||||
printf("ERROR: Failed to export buffer: 0x%lx\n",
|
||||
params->phy_address);
|
||||
err = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Allocated buffer %d of type %d at paddr 0x%08x vaddr %p size %d fd %d\n",
|
||||
printf("Allocated buffer %d of type %d at paddr 0x%lx vaddr %p size %d fd %d\n",
|
||||
i, type, params->phy_address, params->vir_address, size, params->fd);
|
||||
|
||||
memset(&imp_params, 0, sizeof(imp_params));
|
||||
@@ -145,7 +145,7 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Imported fd %d: paddr 0x%08x vaddr %p size %d\n",
|
||||
printf("Imported fd %d: paddr 0x%lx vaddr %p size %d\n",
|
||||
params->fd, params->phy_address, params->vir_address, size);
|
||||
VMEM_release(vmem, &imp_params);
|
||||
}
|
||||
|
||||
@@ -165,7 +165,8 @@ static int sg_table_map(struct device *dev, struct virtio_vdmabuf_buf *exp_buf,
|
||||
case VIRTIO_VDMABUF_HEAP_TYPE_SYSTEM:
|
||||
case VIRTIO_VDMABUF_HEAP_TYPE_SYSTEM_CONTIG:
|
||||
/* SYSTEM, SYSTEM_CONFIG has the same logic */
|
||||
if (dma_map_sgtable(dev, sgt, dir, 0)) {
|
||||
if (dma_map_sgtable(dev, sgt, dir, exp_buf->flags &
|
||||
VIRTIO_VDAMBUF_NONCACHED ? DMA_ATTR_SKIP_CPU_SYNC : 0)) {
|
||||
dev_err(dev, "[%s:%d] error\n",
|
||||
__func__, __LINE__);
|
||||
sg_free_table(sgt);
|
||||
@@ -204,7 +205,8 @@ static int sg_table_unmap(struct device *dev, struct virtio_vdmabuf_buf *exp_buf
|
||||
case VIRTIO_VDMABUF_HEAP_TYPE_USER:
|
||||
case VIRTIO_VDMABUF_HEAP_TYPE_SYSTEM:
|
||||
case VIRTIO_VDMABUF_HEAP_TYPE_SYSTEM_CONTIG:
|
||||
dma_unmap_sgtable(dev, sgt, dir, 0);
|
||||
dma_unmap_sgtable(dev, sgt, dir, exp_buf->flags &
|
||||
VIRTIO_VDAMBUF_NONCACHED ? DMA_ATTR_SKIP_CPU_SYNC : 0);
|
||||
break;
|
||||
|
||||
case VIRTIO_VDMABUF_HEAP_TYPE_CARVEOUT:
|
||||
|
||||
@@ -60,6 +60,7 @@ struct rfkill_wlan_data {
|
||||
|
||||
static struct rfkill_wlan_data *g_rfkill = NULL;
|
||||
static int power_set_time = 0;
|
||||
static int support_power_ctrl = 0; //Used to control whether power switch control is supported.
|
||||
|
||||
static const char wlan_name[] =
|
||||
#if defined (CONFIG_BCM4330)
|
||||
@@ -660,6 +661,15 @@ static int wlan_platdata_parse_dt(struct device *dev,
|
||||
LOG("%s: get property: WIFI,poweren_gpio = %d, flags = %d.\n", __func__, gpio, flags);
|
||||
} else data->power_n.io = -1;
|
||||
gpio = of_get_named_gpio_flags(node, "WIFI,vbat_gpio", 0, &flags);
|
||||
|
||||
if (of_find_property(node, "support_power_ctrl", NULL)) {
|
||||
support_power_ctrl = true;
|
||||
LOG("%s: Turn off the power during suspension and turn it on when resuming, support_power_ctrl = %d.\n", __func__, support_power_ctrl);
|
||||
} else {
|
||||
support_power_ctrl = false;
|
||||
LOG("%s: power is only turned on during initialization and is not controlled afterwards, support_power_ctrl = %d.\n", __func__, support_power_ctrl);
|
||||
}
|
||||
|
||||
if (gpio_is_valid(gpio)) {
|
||||
data->vbat_n.io = gpio;
|
||||
data->vbat_n.enable = (flags == GPIO_ACTIVE_HIGH) ? 1:0;
|
||||
@@ -901,12 +911,53 @@ static int rfkill_wlan_remove(struct platform_device *pdev)
|
||||
|
||||
static int rfkill_wlan_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
struct rfkill_wlan_data *mrfkill = g_rfkill;
|
||||
struct rksdmmc_gpio *poweron, *reset;
|
||||
poweron = &mrfkill->pdata->power_n;
|
||||
reset = &mrfkill->pdata->reset_n;
|
||||
|
||||
// turn off the wifi's power
|
||||
if( support_power_ctrl ){
|
||||
if (gpio_is_valid(poweron->io)) {
|
||||
gpio_set_value(poweron->io, !(poweron->enable));
|
||||
msleep(100);
|
||||
}
|
||||
|
||||
if (gpio_is_valid(reset->io)) {
|
||||
gpio_set_value(reset->io, !(reset->enable));
|
||||
}
|
||||
|
||||
wifi_power_state = 0;
|
||||
LOG("wifi shut off power.\n");
|
||||
}
|
||||
|
||||
LOG("Enter %s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rfkill_wlan_resume(struct platform_device *pdev)
|
||||
{
|
||||
struct rfkill_wlan_data *mrfkill = g_rfkill;
|
||||
struct rksdmmc_gpio *poweron, *reset;
|
||||
poweron = &mrfkill->pdata->power_n;
|
||||
reset = &mrfkill->pdata->reset_n;
|
||||
|
||||
// turn on the wifi's power
|
||||
if( support_power_ctrl ){
|
||||
if (gpio_is_valid(poweron->io)) {
|
||||
gpio_set_value(poweron->io, poweron->enable);
|
||||
msleep(500);
|
||||
}
|
||||
|
||||
if (gpio_is_valid(reset->io)) {
|
||||
gpio_set_value(reset->io, reset->enable);
|
||||
msleep(100);
|
||||
}
|
||||
|
||||
wifi_power_state = 1;
|
||||
LOG("wifi turn on power. %d\n", poweron->io);
|
||||
}
|
||||
|
||||
LOG("Enter %s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user