mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
Merge commit '438259ec8c6f9b3659cc27d54f01e2a224b1c615'
* commit '438259ec8c6f9b3659cc27d54f01e2a224b1c615': media: rockchip: vicap fixes error use_count for switch device mode media: rockchip: vicap fixes error start stream of aov for rv1126b arm64: dts: rockchip: rk3562: remove unnecessary references to rkcif_mmu arm64: dts: rockchip: rv1126b-evb-cam-csi0: add imx586 support ARM: configs: rv1126b-evb: enable imx586 arm64: dts: rockchip: rk3588-evb7-v11: support usbhost3.0 iio: imu: inv_icm42670: fix dead lock when resume video: rockchip: mpp: rkvenc2: add governor and device for devfreq thermal: rockchip: Remove npu thermal for rv1126b arm64: dts: rockchip: rv1126b: Remove npu thermal video: rockchip: mpp_osal: Add func to get dma iommu mapping arm64: dts: rockchip: rv1126b: add opp-510M/600M for npu clk: rockchip: clk-pvtpll: add 510M/600M frequency point for rv1126b npu arm64: dts: rockchip: rk3528: Remove pcie2x1 SRST_PRESETN_CRU_PCIE reset arm64: dts: rockchip: rv1126b-evb1-v10: Adapt the PMU IO states for the sleep mode arm64: dts: rockchip: rv1126b-evb3-v10: Add rtc/rockchip_suspend support arm64: dts: rockchip: rv1126b: Add label to reserved-memory node arm64: dts: rockchip: rv1126b-evb2-v10: Resolve the leakage issue in sleep mode media: i2c: sc850sl: add support hw standby Change-Id: I56bc3ae8f65e08842488163fbe4ab6791b2f5a5a
This commit is contained in:
@@ -47,6 +47,7 @@ CONFIG_VIDEOBUF2_DMA_SG=y
|
||||
CONFIG_VIDEO_GC2053=m
|
||||
CONFIG_VIDEO_GC8613=m
|
||||
CONFIG_VIDEO_IMX415=m
|
||||
CONFIG_VIDEO_IMX586=m
|
||||
CONFIG_VIDEO_OS04A10=m
|
||||
CONFIG_VIDEO_PS5458=m
|
||||
# CONFIG_VIDEO_RK_IRCUT is not set
|
||||
|
||||
@@ -621,9 +621,8 @@
|
||||
<0x0 0xfe000000 0x0 0x400000>,
|
||||
<0x0 0xfc000000 0x0 0x100000>;
|
||||
reg-names = "pcie-apb", "pcie-dbi", "config";
|
||||
resets = <&cru SRST_RESETN_PCIE_POWER_UP>, <&cru SRST_PRESETN_PCIE>,
|
||||
<&cru SRST_PRESETN_CRU_PCIE>;
|
||||
reset-names = "pcie", "periph", "preset_cru";
|
||||
resets = <&cru SRST_RESETN_PCIE_POWER_UP>, <&cru SRST_PRESETN_PCIE>;
|
||||
reset-names = "pcie", "periph";
|
||||
status = "disabled";
|
||||
|
||||
pcie2x1_intc: legacy-interrupt-controller {
|
||||
|
||||
@@ -709,7 +709,6 @@
|
||||
rkcif_mipi_lvds: rkcif-mipi-lvds {
|
||||
compatible = "rockchip,rkcif-mipi-lvds";
|
||||
rockchip,hw = <&rkcif>;
|
||||
iommus = <&rkcif_mmu>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -740,7 +739,6 @@
|
||||
rkcif_mipi_lvds1: rkcif-mipi-lvds1 {
|
||||
compatible = "rockchip,rkcif-mipi-lvds";
|
||||
rockchip,hw = <&rkcif>;
|
||||
iommus = <&rkcif_mmu>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -771,7 +769,6 @@
|
||||
rkcif_mipi_lvds2: rkcif-mipi-lvds2 {
|
||||
compatible = "rockchip,rkcif-mipi-lvds";
|
||||
rockchip,hw = <&rkcif>;
|
||||
iommus = <&rkcif_mmu>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -802,7 +799,6 @@
|
||||
rkcif_mipi_lvds3: rkcif-mipi-lvds3 {
|
||||
compatible = "rockchip,rkcif-mipi-lvds";
|
||||
rockchip,hw = <&rkcif>;
|
||||
iommus = <&rkcif_mmu>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
||||
@@ -937,11 +937,11 @@
|
||||
};
|
||||
|
||||
&usbhost3_0 {
|
||||
status = "disabled";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usbhost_dwc3_0 {
|
||||
status = "disabled";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&work_led {
|
||||
|
||||
@@ -56,6 +56,12 @@
|
||||
remote-endpoint = <&sc635hai_out>;
|
||||
data-lanes = <1 2 3 4>;
|
||||
};
|
||||
|
||||
csi_dphy_input7: endpoint@8 {
|
||||
reg = <8>;
|
||||
remote-endpoint = <&imx586_out>;
|
||||
data-lanes = <1 2 3 4>;
|
||||
};
|
||||
};
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
@@ -115,6 +121,26 @@
|
||||
};
|
||||
};
|
||||
|
||||
imx586: imx586@1a {
|
||||
compatible = "sony,imx586";
|
||||
reg = <0x1a>;
|
||||
clocks = <&cru CLK_MIPI0_OUT2IO>;
|
||||
clock-names = "xvclk";
|
||||
reset-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cam_clk0_pins>;
|
||||
rockchip,camera-module-index = <0>;
|
||||
rockchip,camera-module-facing = "back";
|
||||
rockchip,camera-module-name = "default";
|
||||
rockchip,camera-module-lens-name = "default";
|
||||
port {
|
||||
imx586_out: endpoint {
|
||||
remote-endpoint = <&csi_dphy_input7>;
|
||||
data-lanes = <1 2 3 4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
sc450ai: sc450ai@30 {
|
||||
compatible = "smartsens,sc450ai";
|
||||
status = "okay";
|
||||
|
||||
@@ -28,9 +28,130 @@
|
||||
|
||||
rockchip,sleep-pin-config = <
|
||||
(0
|
||||
| RKPM_SLEEP_PIN0_EN
|
||||
| RKPM_SLEEP_PIN2_EN
|
||||
)
|
||||
(0
|
||||
| RKPM_SLEEP_PIN0_ACT_LOW
|
||||
)
|
||||
>;
|
||||
|
||||
rockchip,sleep-io-config = <
|
||||
/* pmic_sleep */
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_DOWN
|
||||
| RKPM_IO_CFG_ID(0)
|
||||
)
|
||||
/* reset */
|
||||
#if 0
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_NONE
|
||||
| RKPM_IO_CFG_ID(1)
|
||||
)
|
||||
#endif
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_DOWN
|
||||
| RKPM_IO_CFG_ID(2)
|
||||
)
|
||||
(0
|
||||
| RKPM_IO_CFG_PULL_NONE
|
||||
| RKPM_IO_CFG_ID(3)
|
||||
)
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_DOWN
|
||||
| RKPM_IO_CFG_ID(4)
|
||||
)
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_UP
|
||||
| RKPM_IO_CFG_ID(5)
|
||||
)
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_DOWN
|
||||
| RKPM_IO_CFG_ID(6)
|
||||
)
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_UP
|
||||
| RKPM_IO_CFG_ID(7)
|
||||
)
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_DOWN
|
||||
| RKPM_IO_CFG_ID(8)
|
||||
)
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_DOWN
|
||||
| RKPM_IO_CFG_ID(9)
|
||||
)
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_DOWN
|
||||
| RKPM_IO_CFG_ID(10)
|
||||
)
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_DOWN
|
||||
| RKPM_IO_CFG_ID(11)
|
||||
)
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_DOWN
|
||||
| RKPM_IO_CFG_ID(12)
|
||||
)
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_DOWN
|
||||
| RKPM_IO_CFG_ID(20)
|
||||
)
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_DOWN
|
||||
| RKPM_IO_CFG_ID(21)
|
||||
)
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_DOWN
|
||||
| RKPM_IO_CFG_ID(22)
|
||||
)
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_DOWN
|
||||
| RKPM_IO_CFG_ID(23)
|
||||
)
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_DOWN
|
||||
| RKPM_IO_CFG_ID(24)
|
||||
)
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_DOWN
|
||||
| RKPM_IO_CFG_ID(25)
|
||||
)
|
||||
>;
|
||||
};
|
||||
|
||||
@@ -274,7 +274,7 @@
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <900000>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -441,6 +441,10 @@
|
||||
| RKPM_IO_CFG_ID(2)
|
||||
)
|
||||
(0
|
||||
| RKPM_IO_CFG_PULL_NONE
|
||||
| RKPM_IO_CFG_ID(3)
|
||||
)
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_UP
|
||||
@@ -479,22 +483,20 @@
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_UP
|
||||
| RKPM_IO_CFG_PULL_DOWN
|
||||
| RKPM_IO_CFG_ID(10)
|
||||
)
|
||||
/* uart0 tx */
|
||||
#if 0
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_UP
|
||||
| RKPM_IO_CFG_PULL_DOWN
|
||||
| RKPM_IO_CFG_ID(11)
|
||||
)
|
||||
#endif
|
||||
(0
|
||||
| RKPM_IO_CFG_IOMUX_GPIO
|
||||
| RKPM_IO_CFG_GPIO_DIR_INPUT
|
||||
| RKPM_IO_CFG_PULL_UP
|
||||
| RKPM_IO_CFG_PULL_DOWN
|
||||
| RKPM_IO_CFG_ID(12)
|
||||
)
|
||||
(0
|
||||
|
||||
@@ -448,6 +448,28 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&rockchip_suspend {
|
||||
status = "okay";
|
||||
|
||||
rockchip,sleep-pin-config = <
|
||||
(0
|
||||
)
|
||||
>;
|
||||
rockchip,sleep-mode-config = <
|
||||
(0
|
||||
| RKPM_SLP_ARMOFF_LOGOFF
|
||||
| RKPM_SLP_PMU_PMUALIVE_32K
|
||||
| RKPM_SLP_PMU_DIS_OSC
|
||||
| RKPM_SLP_LP_PR
|
||||
)
|
||||
>;
|
||||
};
|
||||
|
||||
&rtc {
|
||||
rockchip,rtc-suspend-bypass;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
sdio-pwrseq {
|
||||
wifi_enable_h: wifi-enable-h {
|
||||
|
||||
@@ -580,7 +580,7 @@
|
||||
method = "smc";
|
||||
};
|
||||
|
||||
reserved-memory {
|
||||
reserved_memory: reserved-memory {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
@@ -915,20 +915,6 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
npu_thermal: npu-thermal {
|
||||
polling-delay-passive = <20>; /* milliseconds */
|
||||
polling-delay = <1000>; /* milliseconds */
|
||||
thermal-sensors = <&tsadc 1>;
|
||||
trips {
|
||||
bigcore_crit: bigcore-crit {
|
||||
/* millicelsius */
|
||||
temperature = <115000>;
|
||||
/* millicelsius */
|
||||
hysteresis = <2000>;
|
||||
type = "critical";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
timer {
|
||||
@@ -3331,6 +3317,18 @@
|
||||
opp-microvolt-L0 = <900000 900000 1050000>;
|
||||
opp-microvolt-L1 = <875000 875000 1050000>;
|
||||
};
|
||||
opp-510000000 {
|
||||
opp-hz = /bits/ 64 <510000000>;
|
||||
opp-microvolt = <850000 850000 1050000>;
|
||||
opp-microvolt-L0 = <900000 900000 1050000>;
|
||||
opp-microvolt-L1 = <875000 875000 1050000>;
|
||||
};
|
||||
opp-600000000 {
|
||||
opp-hz = /bits/ 64 <600000000>;
|
||||
opp-microvolt = <850000 850000 1050000>;
|
||||
opp-microvolt-L0 = <900000 900000 1050000>;
|
||||
opp-microvolt-L1 = <875000 875000 1050000>;
|
||||
};
|
||||
opp-700000000 {
|
||||
opp-hz = /bits/ 64 <700000000>;
|
||||
opp-microvolt = <850000 850000 1050000>;
|
||||
|
||||
@@ -193,6 +193,8 @@ static struct pvtpll_table rv1126b_npu_pvtpll_table[] = {
|
||||
ROCKCHIP_PVTPLL_VOLT_SEL(900000000, 0, 14, 1),
|
||||
ROCKCHIP_PVTPLL_VOLT_SEL(800000000, 0, 18, 1),
|
||||
ROCKCHIP_PVTPLL_VOLT_SEL(700000000, 0, 36, 3),
|
||||
ROCKCHIP_PVTPLL_VOLT_SEL(600000000, 0, 60, 3),
|
||||
ROCKCHIP_PVTPLL_VOLT_SEL(510000000, 0, 108, 3),
|
||||
};
|
||||
|
||||
static struct pvtpll_table rk3506_core_pvtpll_table[] = {
|
||||
|
||||
@@ -1342,17 +1342,8 @@ static int __maybe_unused sleep_icm42670_resume(struct device *dev)
|
||||
struct icm42670_data *st = iio_priv(dev_get_drvdata(dev));
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
|
||||
mutex_lock(&st->lock);
|
||||
|
||||
if (!pm_runtime_suspended(dev))
|
||||
goto out_unlock;
|
||||
|
||||
usleep_range(3000, 4000);
|
||||
|
||||
pm_runtime_disable(dev);
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
icm42670_set_odr(st, ICM42670_GYRO, st->gyro_frequency_buff);
|
||||
icm42670_set_odr(st, ICM42670_ACCEL, st->accel_frequency_buff);
|
||||
icm42670_set_lpf_bw(st, ICM42670_ACCEL, st->accel_lpf_bw_buff);
|
||||
@@ -1360,8 +1351,6 @@ static int __maybe_unused sleep_icm42670_resume(struct device *dev)
|
||||
|
||||
ret = icm42670_set_enable(indio_dev, 1);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&st->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1375,11 +1364,6 @@ static int __maybe_unused sleep_icm42670_suspend(struct device *dev)
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&st->lock);
|
||||
|
||||
if (pm_runtime_suspended(dev))
|
||||
goto out_unlock;
|
||||
|
||||
st->gyro_frequency_buff = st->gyro_frequency;
|
||||
st->accel_frequency_buff = st->accel_frequency;
|
||||
st->accel_lpf_bw_buff = st->accel_lpf_bw;
|
||||
@@ -1387,8 +1371,6 @@ static int __maybe_unused sleep_icm42670_suspend(struct device *dev)
|
||||
|
||||
ret = icm42670_set_enable(indio_dev, 0);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&st->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* V0.0X01.0X02 change power_gpio to pwdn_gpio
|
||||
* V0.0X01.0X03 support thunder boot
|
||||
* V0.0X01.0X04 support sleep/wake up
|
||||
* V0.0X01.0X05 unified standby hw mode
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -33,7 +34,7 @@
|
||||
#include "../platform/rockchip/isp/rkisp_tb_helper.h"
|
||||
#include "cam-sleep-wakeup.h"
|
||||
|
||||
#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x04)
|
||||
#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x05)
|
||||
|
||||
#ifndef V4L2_CID_DIGITAL_GAIN
|
||||
#define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
|
||||
@@ -121,7 +122,7 @@
|
||||
#define SC850SL_LGAIN 0
|
||||
#define SC850SL_SGAIN 1
|
||||
|
||||
static const char * const sc850sl_supply_names[] = {
|
||||
static const char *const sc850sl_supply_names[] = {
|
||||
"dvdd", // Digital core power
|
||||
"dovdd", // Digital I/O power
|
||||
"avdd", // Analog power
|
||||
@@ -181,10 +182,12 @@ struct sc850sl {
|
||||
const char *module_facing;
|
||||
const char *module_name;
|
||||
const char *len_name;
|
||||
u32 standby_hw;
|
||||
u32 cur_vts;
|
||||
bool has_init_exp;
|
||||
bool is_thunderboot;
|
||||
bool is_first_streamoff;
|
||||
bool is_standby;
|
||||
struct preisp_hdrae_exp_s init_hdrae_exp;
|
||||
struct cam_sw_info *cam_sw_info;
|
||||
};
|
||||
@@ -413,7 +416,7 @@ static const struct sc850sl_mode supported_modes[] = {
|
||||
.denominator = 300000,
|
||||
},
|
||||
.exp_def = 0x08c0,
|
||||
.hts_def = 0x0226*5-0x180,
|
||||
.hts_def = 0x0226 * 5 - 0x180,
|
||||
.vts_def = 0x08ca,
|
||||
.bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
|
||||
.reg_list = sc850sl_linear10bit_3840x2160_regs,
|
||||
@@ -428,7 +431,7 @@ static const u32 bus_code[] = {
|
||||
MEDIA_BUS_FMT_SBGGR10_1X10,
|
||||
};
|
||||
|
||||
static const char * const sc850sl_test_pattern_menu[] = {
|
||||
static const char *const sc850sl_test_pattern_menu[] = {
|
||||
"Disabled",
|
||||
"Vertical Color Bar Type 1",
|
||||
"Vertical Color Bar Type 2",
|
||||
@@ -442,7 +445,7 @@ static const s64 link_freq_items[] = {
|
||||
|
||||
/* Write registers up to 4 at a time */
|
||||
static int sc850sl_write_reg(struct i2c_client *client, u16 reg,
|
||||
u32 len, u32 val)
|
||||
u32 len, u32 val)
|
||||
{
|
||||
u32 buf_i, val_i;
|
||||
u8 buf[6];
|
||||
@@ -470,21 +473,21 @@ static int sc850sl_write_reg(struct i2c_client *client, u16 reg,
|
||||
}
|
||||
|
||||
static int sc850sl_write_array(struct i2c_client *client,
|
||||
const struct regval *regs)
|
||||
const struct regval *regs)
|
||||
{
|
||||
u32 i;
|
||||
int ret = 0;
|
||||
|
||||
for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) {
|
||||
ret = sc850sl_write_reg(client, regs[i].addr,
|
||||
SC850SL_REG_VALUE_08BIT, regs[i].val);
|
||||
SC850SL_REG_VALUE_08BIT, regs[i].val);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Read registers up to 4 at a time */
|
||||
static int sc850sl_read_reg(struct i2c_client *client, u16 reg, unsigned int len,
|
||||
u32 *val)
|
||||
u32 *val)
|
||||
{
|
||||
struct i2c_msg msgs[2];
|
||||
u8 *data_be_p;
|
||||
@@ -518,7 +521,7 @@ static int sc850sl_read_reg(struct i2c_client *client, u16 reg, unsigned int len
|
||||
}
|
||||
|
||||
static int sc850sl_get_reso_dist(const struct sc850sl_mode *mode,
|
||||
struct v4l2_mbus_framefmt *framefmt)
|
||||
struct v4l2_mbus_framefmt *framefmt)
|
||||
{
|
||||
return abs(mode->width - framefmt->width) +
|
||||
abs(mode->height - framefmt->height);
|
||||
@@ -555,12 +558,12 @@ static void sc850sl_change_mode(struct sc850sl *sc850sl, const struct sc850sl_mo
|
||||
sc850sl->cur_mode = mode;
|
||||
sc850sl->cur_vts = sc850sl->cur_mode->vts_def;
|
||||
dev_info(&sc850sl->client->dev, "set fmt: cur_mode: %dx%d, hdr: %d\n",
|
||||
mode->width, mode->height, mode->hdr_mode);
|
||||
mode->width, mode->height, mode->hdr_mode);
|
||||
}
|
||||
|
||||
static int sc850sl_set_fmt(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_format *fmt)
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_format *fmt)
|
||||
{
|
||||
struct sc850sl *sc850sl = to_sc850sl(sd);
|
||||
const struct sc850sl_mode *mode;
|
||||
@@ -592,7 +595,7 @@ static int sc850sl_set_fmt(struct v4l2_subdev *sd,
|
||||
1, vblank_def);
|
||||
__v4l2_ctrl_s_ctrl(sc850sl->link_freq, mode->mipi_freq_idx);
|
||||
pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] /
|
||||
mode->bpp * 2 * SC850SL_4LANES;
|
||||
mode->bpp * 2 * SC850SL_4LANES;
|
||||
__v4l2_ctrl_s_ctrl_int64(sc850sl->pixel_rate, pixel_rate);
|
||||
sc850sl->cur_fps = mode->max_fps;
|
||||
sc850sl->cur_vts = mode->vts_def;
|
||||
@@ -604,8 +607,8 @@ static int sc850sl_set_fmt(struct v4l2_subdev *sd,
|
||||
}
|
||||
|
||||
static int sc850sl_get_fmt(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_format *fmt)
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_format *fmt)
|
||||
{
|
||||
struct sc850sl *sc850sl = to_sc850sl(sd);
|
||||
const struct sc850sl_mode *mode = sc850sl->cur_mode;
|
||||
@@ -634,8 +637,8 @@ static int sc850sl_get_fmt(struct v4l2_subdev *sd,
|
||||
}
|
||||
|
||||
static int sc850sl_enum_mbus_code(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_mbus_code_enum *code)
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_mbus_code_enum *code)
|
||||
{
|
||||
if (code->index >= ARRAY_SIZE(bus_code))
|
||||
return -EINVAL;
|
||||
@@ -645,8 +648,8 @@ static int sc850sl_enum_mbus_code(struct v4l2_subdev *sd,
|
||||
}
|
||||
|
||||
static int sc850sl_enum_frame_sizes(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_frame_size_enum *fse)
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_frame_size_enum *fse)
|
||||
{
|
||||
struct sc850sl *sc850sl = to_sc850sl(sd);
|
||||
|
||||
@@ -670,18 +673,18 @@ static int sc850sl_enable_test_pattern(struct sc850sl *sc850sl, u32 pattern)
|
||||
int ret = 0;
|
||||
|
||||
ret = sc850sl_read_reg(sc850sl->client, SC850SL_REG_TEST_PATTERN,
|
||||
SC850SL_REG_VALUE_08BIT, &val);
|
||||
SC850SL_REG_VALUE_08BIT, &val);
|
||||
if (pattern)
|
||||
val |= SC850SL_TEST_PATTERN_ENABLE;
|
||||
else
|
||||
val &= ~SC850SL_TEST_PATTERN_ENABLE;
|
||||
ret |= sc850sl_write_reg(sc850sl->client, SC850SL_REG_TEST_PATTERN,
|
||||
SC850SL_REG_VALUE_08BIT, val);
|
||||
SC850SL_REG_VALUE_08BIT, val);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sc850sl_g_frame_interval(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_frame_interval *fi)
|
||||
struct v4l2_subdev_frame_interval *fi)
|
||||
{
|
||||
struct sc850sl *sc850sl = to_sc850sl(sd);
|
||||
const struct sc850sl_mode *mode = sc850sl->cur_mode;
|
||||
@@ -718,7 +721,7 @@ static const struct sc850sl_mode *sc850sl_find_mode(struct sc850sl *sc850sl, int
|
||||
}
|
||||
|
||||
static int sc850sl_s_frame_interval(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_frame_interval *fi)
|
||||
struct v4l2_subdev_frame_interval *fi)
|
||||
{
|
||||
struct sc850sl *sc850sl = to_sc850sl(sd);
|
||||
const struct sc850sl_mode *mode = NULL;
|
||||
@@ -764,7 +767,7 @@ static int sc850sl_s_frame_interval(struct v4l2_subdev *sd,
|
||||
}
|
||||
|
||||
static int sc850sl_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
|
||||
struct v4l2_mbus_config *config)
|
||||
struct v4l2_mbus_config *config)
|
||||
{
|
||||
config->type = V4L2_MBUS_CSI2_DPHY;
|
||||
config->bus.mipi_csi2.num_data_lanes = SC850SL_4LANES;
|
||||
@@ -773,7 +776,7 @@ static int sc850sl_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
|
||||
}
|
||||
|
||||
static void sc850sl_get_module_inf(struct sc850sl *sc850sl,
|
||||
struct rkmodule_inf *inf)
|
||||
struct rkmodule_inf *inf)
|
||||
{
|
||||
memset(inf, 0, sizeof(*inf));
|
||||
strscpy(inf->base.sensor, SC850SL_NAME, sizeof(inf->base.sensor));
|
||||
@@ -785,11 +788,11 @@ static void sc850sl_get_module_inf(struct sc850sl *sc850sl,
|
||||
/* mode: 0 = lgain 1 = sgain */
|
||||
static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode)
|
||||
{
|
||||
u32 ANA_Fine_gainx64 = 1, DIG_Fine_gainx1000 = 1;
|
||||
u32 ANA_Fine_gainx64 = 1;
|
||||
u32 Dcg_gainx1000;
|
||||
u8 Coarse_gain = 1, DIG_gain = 1;
|
||||
u8 ANA_Fine_gain_reg = 0x40, DIG_Fine_gain_reg = 0;
|
||||
u8 Dcg_gain_reg, Coarse_gain_reg, DIG_gain_reg;
|
||||
u8 Coarse_gain_reg, DIG_gain_reg;
|
||||
int ret = 0;
|
||||
u64 val = 0;
|
||||
|
||||
@@ -803,8 +806,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode)
|
||||
Dcg_gainx1000 = 1000;
|
||||
Coarse_gain = 1;
|
||||
DIG_gain = 1;
|
||||
DIG_Fine_gainx1000 = 1000;
|
||||
Dcg_gain_reg = 0;
|
||||
Coarse_gain_reg = 0x03;
|
||||
DIG_gain_reg = 0x0;
|
||||
DIG_Fine_gain_reg = 0x80;
|
||||
@@ -812,8 +813,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode)
|
||||
Dcg_gainx1000 = 1000;
|
||||
Coarse_gain = 2;
|
||||
DIG_gain = 1;
|
||||
DIG_Fine_gainx1000 = 1000;
|
||||
Dcg_gain_reg = 0;
|
||||
Coarse_gain_reg = 0x07;
|
||||
DIG_gain_reg = 0x0;
|
||||
DIG_Fine_gain_reg = 0x80;
|
||||
@@ -821,8 +820,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode)
|
||||
Dcg_gainx1000 = 3125;
|
||||
Coarse_gain = 1;
|
||||
DIG_gain = 1;
|
||||
DIG_Fine_gainx1000 = 1000;
|
||||
Dcg_gain_reg = 1;
|
||||
Coarse_gain_reg = 0x23;
|
||||
DIG_gain_reg = 0x0;
|
||||
DIG_Fine_gain_reg = 0x80;
|
||||
@@ -830,8 +827,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode)
|
||||
Dcg_gainx1000 = 3125;
|
||||
Coarse_gain = 2;
|
||||
DIG_gain = 1;
|
||||
DIG_Fine_gainx1000 = 1000;
|
||||
Dcg_gain_reg = 1;
|
||||
Coarse_gain_reg = 0x27;
|
||||
DIG_gain_reg = 0x0;
|
||||
DIG_Fine_gain_reg = 0x80;
|
||||
@@ -839,8 +834,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode)
|
||||
Dcg_gainx1000 = 3125;
|
||||
Coarse_gain = 4;
|
||||
DIG_gain = 1;
|
||||
DIG_Fine_gainx1000 = 1000;
|
||||
Dcg_gain_reg = 1;
|
||||
Coarse_gain_reg = 0x2f;
|
||||
DIG_gain_reg = 0x0;
|
||||
DIG_Fine_gain_reg = 0x80;
|
||||
@@ -848,8 +841,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode)
|
||||
Dcg_gainx1000 = 3125;
|
||||
Coarse_gain = 8;
|
||||
DIG_gain = 1;
|
||||
DIG_Fine_gainx1000 = 1000;
|
||||
Dcg_gain_reg = 1;
|
||||
Coarse_gain_reg = 0x3f;
|
||||
DIG_gain_reg = 0x0;
|
||||
DIG_Fine_gain_reg = 0x80;
|
||||
@@ -858,7 +849,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode)
|
||||
Coarse_gain = 8;
|
||||
DIG_gain = 1;
|
||||
ANA_Fine_gainx64 = 127;
|
||||
Dcg_gain_reg = 1;
|
||||
Coarse_gain_reg = 0x3f;
|
||||
DIG_gain_reg = 0x0;
|
||||
ANA_Fine_gain_reg = 0x7f;
|
||||
@@ -867,7 +857,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode)
|
||||
Coarse_gain = 8;
|
||||
DIG_gain = 2;
|
||||
ANA_Fine_gainx64 = 127;
|
||||
Dcg_gain_reg = 1;
|
||||
Coarse_gain_reg = 0x3f;
|
||||
DIG_gain_reg = 0x1;
|
||||
ANA_Fine_gain_reg = 0x7f;
|
||||
@@ -876,7 +865,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode)
|
||||
Coarse_gain = 8;
|
||||
DIG_gain = 4;
|
||||
ANA_Fine_gainx64 = 127;
|
||||
Dcg_gain_reg = 1;
|
||||
Coarse_gain_reg = 0x3f;
|
||||
DIG_gain_reg = 0x3;
|
||||
ANA_Fine_gain_reg = 0x7f;
|
||||
@@ -885,7 +873,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode)
|
||||
Coarse_gain = 8;
|
||||
DIG_gain = 8;
|
||||
ANA_Fine_gainx64 = 127;
|
||||
Dcg_gain_reg = 1;
|
||||
Coarse_gain_reg = 0x3f;
|
||||
DIG_gain_reg = 0x7;
|
||||
ANA_Fine_gain_reg = 0x7f;
|
||||
@@ -973,7 +960,7 @@ static long sc850sl_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
*/
|
||||
if (sc850sl->cam_sw_info)
|
||||
memcpy(&sc850sl->cam_sw_info->hdr_ae, (struct preisp_hdrae_exp_s *)(arg),
|
||||
sizeof(struct preisp_hdrae_exp_s));
|
||||
sizeof(struct preisp_hdrae_exp_s));
|
||||
break;
|
||||
|
||||
case RKMODULE_SET_HDR_CFG:
|
||||
@@ -983,14 +970,14 @@ static long sc850sl_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
w = sc850sl->cur_mode->width;
|
||||
h = sc850sl->cur_mode->height;
|
||||
dst_fps = DIV_ROUND_CLOSEST(sc850sl->cur_mode->max_fps.denominator,
|
||||
sc850sl->cur_mode->max_fps.numerator);
|
||||
sc850sl->cur_mode->max_fps.numerator);
|
||||
for (i = 0; i < sc850sl->cfg_num; i++) {
|
||||
if (w == supported_modes[i].width &&
|
||||
h == supported_modes[i].height &&
|
||||
supported_modes[i].hdr_mode == hdr_cfg->hdr_mode &&
|
||||
supported_modes[i].bus_fmt == sc850sl->cur_mode->bus_fmt) {
|
||||
cur_fps = DIV_ROUND_CLOSEST(supported_modes[i].max_fps.denominator,
|
||||
supported_modes[i].max_fps.numerator);
|
||||
supported_modes[i].max_fps.numerator);
|
||||
cur_dist = abs(cur_fps - dst_fps);
|
||||
if (cur_best_fit_dist == -1 || cur_dist < cur_best_fit_dist) {
|
||||
cur_best_fit_dist = cur_dist;
|
||||
@@ -1013,17 +1000,17 @@ static long sc850sl_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
h = mode->vts_def - mode->height;
|
||||
__v4l2_ctrl_modify_range(sc850sl->hblank, w, w, 1, w);
|
||||
__v4l2_ctrl_modify_range(sc850sl->vblank, h,
|
||||
SC850SL_VTS_MAX - mode->height,
|
||||
1, h);
|
||||
SC850SL_VTS_MAX - mode->height,
|
||||
1, h);
|
||||
__v4l2_ctrl_s_ctrl(sc850sl->link_freq, mode->mipi_freq_idx);
|
||||
pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] /
|
||||
mode->bpp * 2 * SC850SL_4LANES;
|
||||
mode->bpp * 2 * SC850SL_4LANES;
|
||||
__v4l2_ctrl_s_ctrl_int64(sc850sl->pixel_rate,
|
||||
pixel_rate);
|
||||
sc850sl->cur_fps = mode->max_fps;
|
||||
sc850sl->cur_vts = mode->vts_def;
|
||||
dev_info(&sc850sl->client->dev,
|
||||
"sensor mode: %d\n", mode->hdr_mode);
|
||||
"sensor mode: %d\n", mode->hdr_mode);
|
||||
}
|
||||
break;
|
||||
case RKMODULE_GET_MODULE_INFO:
|
||||
@@ -1040,25 +1027,31 @@ static long sc850sl_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
stream = *((u32 *)arg);
|
||||
|
||||
if (stream) {
|
||||
ret = sc850sl_write_reg(sc850sl->client, 0x3019,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
0xf0);
|
||||
ret = sc850sl_write_reg(sc850sl->client, 0x3018,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
0x7a);
|
||||
ret = sc850sl_write_reg(sc850sl->client, SC850SL_REG_CTRL_MODE,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
SC850SL_MODE_STREAMING);
|
||||
ret |= sc850sl_write_reg(sc850sl->client, 0x3019,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
0xf0);
|
||||
ret |= sc850sl_write_reg(sc850sl->client, 0x3018,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
0x7a);
|
||||
ret |= sc850sl_write_reg(sc850sl->client, 0x302c,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
0x00);
|
||||
ret |= sc850sl_write_reg(sc850sl->client, SC850SL_REG_CTRL_MODE,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
SC850SL_MODE_STREAMING);
|
||||
} else {
|
||||
ret = sc850sl_write_reg(sc850sl->client, 0x3018,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
0x7f);
|
||||
ret = sc850sl_write_reg(sc850sl->client, 0x3019,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
0xff);
|
||||
ret = sc850sl_write_reg(sc850sl->client, SC850SL_REG_CTRL_MODE,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
SC850SL_MODE_SW_STANDBY);
|
||||
ret |= sc850sl_write_reg(sc850sl->client, 0x3018,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
0x7f);
|
||||
ret |= sc850sl_write_reg(sc850sl->client, 0x3019,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
0xff);
|
||||
ret |= sc850sl_write_reg(sc850sl->client, SC850SL_REG_CTRL_MODE,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
SC850SL_MODE_SW_STANDBY);
|
||||
ret |= sc850sl_write_reg(sc850sl->client, 0x302c,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
0x0f);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1077,7 +1070,7 @@ static long sc850sl_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static long sc850sl_compat_ioctl32(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
void __user *up = compat_ptr(arg);
|
||||
struct rkmodule_inf *inf;
|
||||
@@ -1241,7 +1234,7 @@ static int __sc850sl_start_stream(struct sc850sl *sc850sl)
|
||||
/* In case these controls are set before streaming */
|
||||
if (sc850sl->has_init_exp && sc850sl->cur_mode->hdr_mode != NO_HDR) {
|
||||
ret = sc850sl_ioctl(&sc850sl->subdev, PREISP_CMD_SET_HDRAE_EXP,
|
||||
&sc850sl->init_hdrae_exp);
|
||||
&sc850sl->init_hdrae_exp);
|
||||
if (ret) {
|
||||
dev_err(&sc850sl->client->dev,
|
||||
"init exp fail in hdr mode\n");
|
||||
@@ -1250,7 +1243,7 @@ static int __sc850sl_start_stream(struct sc850sl *sc850sl)
|
||||
}
|
||||
}
|
||||
return sc850sl_write_reg(sc850sl->client, SC850SL_REG_CTRL_MODE,
|
||||
SC850SL_REG_VALUE_08BIT, SC850SL_MODE_STREAMING);
|
||||
SC850SL_REG_VALUE_08BIT, SC850SL_MODE_STREAMING);
|
||||
}
|
||||
|
||||
static int __sc850sl_stop_stream(struct sc850sl *sc850sl)
|
||||
@@ -1272,8 +1265,8 @@ static int sc850sl_s_stream(struct v4l2_subdev *sd, int on)
|
||||
int ret = 0;
|
||||
|
||||
dev_info(&sc850sl->client->dev, "s_stream: %d. %dx%d, hdr: %d, bpp: %d\n",
|
||||
on, sc850sl->cur_mode->width, sc850sl->cur_mode->height,
|
||||
sc850sl->cur_mode->hdr_mode, sc850sl->cur_mode->bpp);
|
||||
on, sc850sl->cur_mode->width, sc850sl->cur_mode->height,
|
||||
sc850sl->cur_mode->hdr_mode, sc850sl->cur_mode->bpp);
|
||||
|
||||
mutex_lock(&sc850sl->mutex);
|
||||
on = !!on;
|
||||
@@ -1328,9 +1321,9 @@ static int sc850sl_s_power(struct v4l2_subdev *sd, int on)
|
||||
}
|
||||
if (!sc850sl->is_thunderboot) {
|
||||
ret |= sc850sl_write_reg(sc850sl->client,
|
||||
SC850SL_SOFTWARE_RESET_REG,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
0x01);
|
||||
SC850SL_SOFTWARE_RESET_REG,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
0x01);
|
||||
if (ret) {
|
||||
v4l2_err(sd, "could not set init registers\n");
|
||||
pm_runtime_put_noidle(&client->dev);
|
||||
@@ -1446,6 +1439,11 @@ static int sc850sl_resume(struct device *dev)
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct sc850sl *sc850sl = to_sc850sl(sd);
|
||||
|
||||
if (sc850sl->standby_hw) {
|
||||
dev_info(dev, "resume standby!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cam_sw_prepare_wakeup(sc850sl->cam_sw_info, dev);
|
||||
|
||||
usleep_range(4000, 5000);
|
||||
@@ -1456,7 +1454,7 @@ static int sc850sl_resume(struct device *dev)
|
||||
|
||||
if (sc850sl->has_init_exp && sc850sl->cur_mode != NO_HDR) { // hdr mode
|
||||
ret = sc850sl_ioctl(&sc850sl->subdev, PREISP_CMD_SET_HDRAE_EXP,
|
||||
&sc850sl->cam_sw_info->hdr_ae);
|
||||
&sc850sl->cam_sw_info->hdr_ae);
|
||||
if (ret) {
|
||||
dev_err(&sc850sl->client->dev, "set exp fail in hdr mode\n");
|
||||
return ret;
|
||||
@@ -1471,6 +1469,11 @@ static int sc850sl_suspend(struct device *dev)
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct sc850sl *sc850sl = to_sc850sl(sd);
|
||||
|
||||
if (sc850sl->standby_hw) {
|
||||
dev_info(dev, "suspend standby!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cam_sw_write_array_cb_init(sc850sl->cam_sw_info, client,
|
||||
(void *)sc850sl->cur_mode->reg_list,
|
||||
(sensor_write_array)sc850sl_write_array);
|
||||
@@ -1508,7 +1511,7 @@ static int sc850sl_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
struct sc850sl *sc850sl = to_sc850sl(sd);
|
||||
struct v4l2_mbus_framefmt *try_fmt =
|
||||
v4l2_subdev_get_try_format(sd, fh->state, 0);
|
||||
v4l2_subdev_get_try_format(sd, fh->state, 0);
|
||||
const struct sc850sl_mode *def_mode = &supported_modes[0];
|
||||
|
||||
mutex_lock(&sc850sl->mutex);
|
||||
@@ -1526,8 +1529,8 @@ static int sc850sl_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
#endif
|
||||
|
||||
static int sc850sl_enum_frame_interval(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_frame_interval_enum *fie)
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_frame_interval_enum *fie)
|
||||
{
|
||||
struct sc850sl *sc850sl = to_sc850sl(sd);
|
||||
|
||||
@@ -1580,7 +1583,7 @@ static int sc850sl_get_selection(struct v4l2_subdev *sd,
|
||||
|
||||
static const struct dev_pm_ops sc850sl_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(sc850sl_runtime_suspend,
|
||||
sc850sl_runtime_resume, NULL)
|
||||
sc850sl_runtime_resume, NULL)
|
||||
SET_LATE_SYSTEM_SLEEP_PM_OPS(sc850sl_suspend, sc850sl_resume)
|
||||
};
|
||||
|
||||
@@ -1631,7 +1634,7 @@ static void sc850sl_modify_fps_info(struct sc850sl *sc850sl)
|
||||
static int sc850sl_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct sc850sl *sc850sl = container_of(ctrl->handler,
|
||||
struct sc850sl, ctrl_handler);
|
||||
struct sc850sl, ctrl_handler);
|
||||
struct i2c_client *client = sc850sl->client;
|
||||
s64 max;
|
||||
int ret = 0;
|
||||
@@ -1649,6 +1652,11 @@ static int sc850sl_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
break;
|
||||
}
|
||||
|
||||
if (sc850sl->standby_hw && sc850sl->is_standby) {
|
||||
dev_dbg(&client->dev, "%s: is_standby=true, will return\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pm_runtime_get_if_in_use(&client->dev))
|
||||
return 0;
|
||||
|
||||
@@ -1661,9 +1669,9 @@ static int sc850sl_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
SC850SL_FETCH_EXP_H(ctrl->val));
|
||||
ret |= sc850sl_write_reg(sc850sl->client,
|
||||
SC850SL_REG_EXP_LONG_M,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
SC850SL_FETCH_EXP_M(ctrl->val));
|
||||
SC850SL_REG_EXP_LONG_M,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
SC850SL_FETCH_EXP_M(ctrl->val));
|
||||
ret |= sc850sl_write_reg(sc850sl->client,
|
||||
SC850SL_REG_EXP_LONG_L,
|
||||
SC850SL_REG_VALUE_08BIT,
|
||||
@@ -1693,7 +1701,7 @@ static int sc850sl_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
break;
|
||||
case V4L2_CID_HFLIP:
|
||||
ret = sc850sl_read_reg(sc850sl->client, SC850SL_FLIP_REG,
|
||||
SC850SL_REG_VALUE_08BIT, &val);
|
||||
SC850SL_REG_VALUE_08BIT, &val);
|
||||
if (ret)
|
||||
break;
|
||||
if (ctrl->val)
|
||||
@@ -1701,11 +1709,11 @@ static int sc850sl_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
else
|
||||
val &= ~SC850SL_MIRROR_MASK;
|
||||
ret |= sc850sl_write_reg(sc850sl->client, SC850SL_FLIP_REG,
|
||||
SC850SL_REG_VALUE_08BIT, val);
|
||||
SC850SL_REG_VALUE_08BIT, val);
|
||||
break;
|
||||
case V4L2_CID_VFLIP:
|
||||
ret = sc850sl_read_reg(sc850sl->client, SC850SL_FLIP_REG,
|
||||
SC850SL_REG_VALUE_08BIT, &val);
|
||||
SC850SL_REG_VALUE_08BIT, &val);
|
||||
if (ret)
|
||||
break;
|
||||
if (ctrl->val)
|
||||
@@ -1713,7 +1721,7 @@ static int sc850sl_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
else
|
||||
val &= ~SC850SL_FLIP_MASK;
|
||||
ret |= sc850sl_write_reg(sc850sl->client, SC850SL_FLIP_REG,
|
||||
SC850SL_REG_VALUE_08BIT, val);
|
||||
SC850SL_REG_VALUE_08BIT, val);
|
||||
break;
|
||||
default:
|
||||
dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
|
||||
@@ -1748,37 +1756,37 @@ static int sc850sl_initialize_controls(struct sc850sl *sc850sl)
|
||||
handler->lock = &sc850sl->mutex;
|
||||
|
||||
sc850sl->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
|
||||
V4L2_CID_LINK_FREQ, 0, 0, link_freq_items);
|
||||
V4L2_CID_LINK_FREQ, 0, 0, link_freq_items);
|
||||
v4l2_ctrl_s_ctrl(sc850sl->link_freq, mode->mipi_freq_idx);
|
||||
|
||||
/* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
|
||||
pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * SC850SL_4LANES;
|
||||
sc850sl->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
|
||||
V4L2_CID_PIXEL_RATE, 0, SC850SL_MAX_PIXEL_RATE,
|
||||
1, pixel_rate);
|
||||
V4L2_CID_PIXEL_RATE, 0, SC850SL_MAX_PIXEL_RATE,
|
||||
1, pixel_rate);
|
||||
|
||||
h_blank = mode->hts_def - mode->width;
|
||||
sc850sl->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
|
||||
h_blank, h_blank, 1, h_blank);
|
||||
h_blank, h_blank, 1, h_blank);
|
||||
if (sc850sl->hblank)
|
||||
sc850sl->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
|
||||
|
||||
vblank_def = mode->vts_def - mode->height;
|
||||
sc850sl->vblank = v4l2_ctrl_new_std(handler, &sc850sl_ctrl_ops,
|
||||
V4L2_CID_VBLANK, vblank_def,
|
||||
SC850SL_VTS_MAX - mode->height,
|
||||
1, vblank_def);
|
||||
V4L2_CID_VBLANK, vblank_def,
|
||||
SC850SL_VTS_MAX - mode->height,
|
||||
1, vblank_def);
|
||||
|
||||
exposure_max = mode->vts_def - 4; /*vts_def 0x08ca=2250*/
|
||||
sc850sl->exposure = v4l2_ctrl_new_std(handler, &sc850sl_ctrl_ops,
|
||||
V4L2_CID_EXPOSURE, SC850SL_EXPOSURE_MIN,
|
||||
exposure_max, SC850SL_EXPOSURE_STEP,
|
||||
mode->exp_def); /*exp_def 0x08c0=2240*/
|
||||
exposure_max = mode->vts_def - 4; /*vts_def 0x08ca=2250*/
|
||||
sc850sl->exposure = v4l2_ctrl_new_std(handler, &sc850sl_ctrl_ops,
|
||||
V4L2_CID_EXPOSURE, SC850SL_EXPOSURE_MIN,
|
||||
exposure_max, SC850SL_EXPOSURE_STEP,
|
||||
mode->exp_def); /*exp_def 0x08c0=2240*/
|
||||
|
||||
sc850sl->anal_a_gain = v4l2_ctrl_new_std(handler, &sc850sl_ctrl_ops,
|
||||
V4L2_CID_ANALOGUE_GAIN, SC850SL_GAIN_MIN,
|
||||
SC850SL_GAIN_MAX, SC850SL_GAIN_STEP,
|
||||
SC850SL_GAIN_DEFAULT);
|
||||
V4L2_CID_ANALOGUE_GAIN, SC850SL_GAIN_MIN,
|
||||
SC850SL_GAIN_MAX, SC850SL_GAIN_STEP,
|
||||
SC850SL_GAIN_DEFAULT);
|
||||
|
||||
sc850sl->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
|
||||
&sc850sl_ctrl_ops, V4L2_CID_TEST_PATTERN,
|
||||
@@ -1791,12 +1799,13 @@ static int sc850sl_initialize_controls(struct sc850sl *sc850sl)
|
||||
if (handler->error) {
|
||||
ret = handler->error;
|
||||
dev_err(&sc850sl->client->dev,
|
||||
"Failed to init controls(%d)\n", ret);
|
||||
"Failed to init controls(%d)\n", ret);
|
||||
goto err_free_handler;
|
||||
}
|
||||
|
||||
sc850sl->subdev.ctrl_handler = handler;
|
||||
sc850sl->has_init_exp = false;
|
||||
sc850sl->is_standby = false;
|
||||
sc850sl->cur_fps = mode->max_fps;
|
||||
sc850sl->cur_vts = mode->vts_def;
|
||||
|
||||
@@ -1809,7 +1818,7 @@ err_free_handler:
|
||||
}
|
||||
|
||||
static int sc850sl_check_sensor_id(struct sc850sl *sc850sl,
|
||||
struct i2c_client *client)
|
||||
struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &sc850sl->client->dev;
|
||||
u32 id = 0;
|
||||
@@ -1820,7 +1829,7 @@ static int sc850sl_check_sensor_id(struct sc850sl *sc850sl,
|
||||
return 0;
|
||||
}
|
||||
ret = sc850sl_read_reg(client, SC850SL_REG_CHIP_ID,
|
||||
SC850SL_REG_VALUE_16BIT, &id);
|
||||
SC850SL_REG_VALUE_16BIT, &id);
|
||||
if (id != CHIP_ID) {
|
||||
dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
|
||||
return -ENODEV;
|
||||
@@ -1844,7 +1853,7 @@ static int sc850sl_configure_regulators(struct sc850sl *sc850sl)
|
||||
}
|
||||
|
||||
static int sc850sl_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
@@ -1855,9 +1864,9 @@ static int sc850sl_probe(struct i2c_client *client,
|
||||
u32 i, hdr_mode = 0;
|
||||
|
||||
dev_info(dev, "driver version: %02x.%02x.%02x",
|
||||
DRIVER_VERSION >> 16,
|
||||
(DRIVER_VERSION & 0xff00) >> 8,
|
||||
DRIVER_VERSION & 0x00ff);
|
||||
DRIVER_VERSION >> 16,
|
||||
(DRIVER_VERSION & 0xff00) >> 8,
|
||||
DRIVER_VERSION & 0x00ff);
|
||||
|
||||
sc850sl = devm_kzalloc(dev, sizeof(*sc850sl), GFP_KERNEL);
|
||||
if (!sc850sl)
|
||||
@@ -1876,6 +1885,10 @@ static int sc850sl_probe(struct i2c_client *client,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Compatible with non-standby mode if this attribute is not configured in dts*/
|
||||
of_property_read_u32(node, RKMODULE_CAMERA_STANDBY_HW,
|
||||
&sc850sl->standby_hw);
|
||||
|
||||
ret = of_property_read_u32(node, OF_CAMERA_HDR_MODE, &hdr_mode);
|
||||
if (ret) {
|
||||
hdr_mode = NO_HDR;
|
||||
@@ -1899,12 +1912,12 @@ static int sc850sl_probe(struct i2c_client *client,
|
||||
}
|
||||
|
||||
sc850sl->reset_gpio = devm_gpiod_get(dev, "reset",
|
||||
sc850sl->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
|
||||
sc850sl->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
|
||||
if (IS_ERR(sc850sl->reset_gpio))
|
||||
dev_warn(dev, "Failed to get reset-gpios\n");
|
||||
|
||||
sc850sl->pwdn_gpio = devm_gpiod_get(dev, "pwdn",
|
||||
sc850sl->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
|
||||
sc850sl->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
|
||||
if (IS_ERR(sc850sl->pwdn_gpio))
|
||||
dev_warn(dev, "Failed to get pwdn_gpio\n");
|
||||
|
||||
|
||||
@@ -5411,6 +5411,7 @@ static void rkcif_stream_stop(struct rkcif_stream *stream)
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
|
||||
atomic_dec_if_positive(&stream->cifdev->id_use_cnt);
|
||||
if (cif_dev->switch_info.is_use_switch) {
|
||||
ret = atomic_dec_if_positive(&cif_dev->hw_dev->switch_stream_cnt[cif_dev->switch_info.host_idx]);
|
||||
if (ret) {
|
||||
@@ -5420,8 +5421,6 @@ static void rkcif_stream_stop(struct rkcif_stream *stream)
|
||||
}
|
||||
}
|
||||
|
||||
atomic_dec_if_positive(&stream->cifdev->id_use_cnt);
|
||||
|
||||
if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY ||
|
||||
mbus_cfg->type == V4L2_MBUS_CSI2_CPHY ||
|
||||
mbus_cfg->type == V4L2_MBUS_CCP2) {
|
||||
@@ -14257,7 +14256,8 @@ static int rkcif_terminal_sensor_set_stream(struct rkcif_device *cif_dev, int on
|
||||
rkcif_set_sof(cif_dev, cif_dev->stream[0].frame_idx);
|
||||
if (p->subdevs[i] == terminal_sensor->sd &&
|
||||
(cif_dev->chip_id == CHIP_RV1106_CIF ||
|
||||
cif_dev->chip_id == CHIP_RV1103B_CIF)) {
|
||||
cif_dev->chip_id == CHIP_RV1103B_CIF ||
|
||||
cif_dev->chip_id == CHIP_RV1126B_CIF)) {
|
||||
if (!rk_tb_mcu_is_done() && on) {
|
||||
cif_dev->tb_client.data = p->subdevs[i];
|
||||
cif_dev->tb_client.cb = rkcif_sensor_quick_streaming_cb;
|
||||
|
||||
@@ -337,16 +337,13 @@ struct rockchip_thermal_data {
|
||||
#define RV1126B_GRF_TSADC_CON1 0x54
|
||||
#define RV1126B_GRF_TSADC_CON6 0x68
|
||||
#define RV1126B_GRF_TSADC_ST1 0x114
|
||||
#define RV1126B_CH_EN 0x300
|
||||
#define RV1126B_CH_EN_MASK (0x300 << 16)
|
||||
#define RV1126B_UNLOCK_VALUE 0xa5
|
||||
#define RV1126B_UNLOCK_VALUE_MASK (0xff << 16)
|
||||
#define RV1126B_UNLOCK_TRIGGER BIT(8)
|
||||
#define RV1126B_UNLOCK_TRIGGER_MASK (BIT(8) << 16)
|
||||
#define RV1126B_MAX_BIAS 0x7f
|
||||
#define RV1126B_BIAS_MASK (0x7f << 16)
|
||||
#define RV1126B_SW_CTRL 0x8028
|
||||
#define RV1126B_SW_CTRL_MASK (0x8078 << 16)
|
||||
#define RV1126B_CTRL_MASK (0x8078 << 16)
|
||||
|
||||
#define GRF_SARADC_TESTBIT_ON (0x10001 << 2)
|
||||
#define GRF_TSADC_TESTBIT_H_ON (0x10001 << 2)
|
||||
@@ -1409,13 +1406,7 @@ static int rk_tsadcv5_get_temp(const struct chip_tsadc_table *table,
|
||||
{
|
||||
u32 val;
|
||||
|
||||
if (chn == 0)
|
||||
val = readl_relaxed(regs + TSADCV3_DATA(1));
|
||||
else if (chn == 1)
|
||||
val = readl_relaxed(regs + TSADCV3_DATA(0));
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
val = readl_relaxed(regs + TSADCV3_DATA(chn));
|
||||
*temp = val & TSADCV6_DATA_MASK;
|
||||
if (val & TSADC_DATA_SIGN_BIT)
|
||||
*temp |= TSADC_DATA_NEGATIVE;
|
||||
@@ -1698,10 +1689,7 @@ static void rv1126b_tsadc_phy_init(struct device *dev, struct regmap *grf,
|
||||
}
|
||||
regmap_read(grf, RV1126B_GRF_TSADC_ST1, &val);
|
||||
dev_info(dev, "width=0x%x, bias=0x%x\n", val, phy_cfg->bias);
|
||||
regmap_write(grf, RV1126B_GRF_TSADC_CON6,
|
||||
RV1126B_CH_EN | RV1126B_CH_EN_MASK);
|
||||
regmap_write(grf, RV1126B_GRF_TSADC_CON0,
|
||||
RV1126B_SW_CTRL | RV1126B_SW_CTRL_MASK);
|
||||
regmap_write(grf, RV1126B_GRF_TSADC_CON0, RV1126B_CTRL_MASK);
|
||||
regmap_write(grf, RV1126B_GRF_TSADC_CON1,
|
||||
RV1126B_UNLOCK_VALUE | RV1126B_UNLOCK_VALUE_MASK);
|
||||
regmap_write(grf, RV1126B_GRF_TSADC_CON1,
|
||||
@@ -1829,8 +1817,8 @@ static const struct rockchip_tsadc_chip rv1126_tsadc_data = {
|
||||
};
|
||||
|
||||
static const struct rockchip_tsadc_chip rv1126b_tsadc_data = {
|
||||
.chn_id = {0, 1}, /* cpu, npu */
|
||||
.chn_num = 2, /* two channels for tsadc */
|
||||
.chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */
|
||||
.chn_num = 1, /* one channel for tsadc */
|
||||
.tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */
|
||||
.tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */
|
||||
.tshut_temp = 95000,
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
#include <soc/rockchip/rockchip_system_monitor.h>
|
||||
#include <soc/rockchip/rockchip_iommu.h>
|
||||
|
||||
#ifdef CONFIG_PM_DEVFREQ
|
||||
#include "../../../devfreq/governor.h"
|
||||
#endif
|
||||
|
||||
#include "mpp_debug.h"
|
||||
#include "mpp_iommu.h"
|
||||
#include "mpp_common.h"
|
||||
@@ -53,6 +57,10 @@
|
||||
#define to_rkvenc_dev(dev) \
|
||||
container_of(dev, struct rkvenc_dev, mpp)
|
||||
|
||||
#ifdef CONFIG_PM_DEVFREQ
|
||||
static DEFINE_MUTEX(venc_governor_mutex);
|
||||
static int venc_governor_count;
|
||||
#endif
|
||||
|
||||
enum RKVENC_FORMAT_TYPE {
|
||||
RKVENC_FMT_BASE = 0x0000,
|
||||
@@ -328,6 +336,9 @@ struct rkvenc_dev {
|
||||
u32 bs_overflow;
|
||||
|
||||
#ifdef CONFIG_PM_DEVFREQ
|
||||
struct devfreq *devfreq;
|
||||
unsigned long core_rate_hz;
|
||||
unsigned long core_current_rate_hz;
|
||||
struct rockchip_opp_info opp_info;
|
||||
struct monitor_dev_info *mdev_info;
|
||||
#endif
|
||||
@@ -2127,6 +2138,90 @@ static inline int rkvenc_procfs_ccu_init(struct mpp_dev *mpp)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM_DEVFREQ
|
||||
static int rkvenc_devfreq_target(struct device *dev,
|
||||
unsigned long *freq, u32 flags)
|
||||
{
|
||||
struct mpp_dev *mpp = dev_get_drvdata(dev);
|
||||
struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
|
||||
struct devfreq *devfreq = enc->devfreq;
|
||||
struct rockchip_opp_info *opp_info = &enc->opp_info;
|
||||
struct dev_pm_opp *opp;
|
||||
int ret = 0;
|
||||
|
||||
if (!opp_info->is_rate_volt_checked)
|
||||
return -EINVAL;
|
||||
|
||||
opp = devfreq_recommended_opp(dev, freq, flags);
|
||||
if (IS_ERR(opp))
|
||||
return PTR_ERR(opp);
|
||||
dev_pm_opp_put(opp);
|
||||
|
||||
if (*freq == enc->core_current_rate_hz)
|
||||
return 0;
|
||||
|
||||
rockchip_opp_dvfs_lock(opp_info);
|
||||
if (pm_runtime_active(dev))
|
||||
opp_info->is_runtime_active = true;
|
||||
else
|
||||
opp_info->is_runtime_active = false;
|
||||
ret = dev_pm_opp_set_rate(dev, *freq);
|
||||
if (!ret) {
|
||||
enc->core_current_rate_hz = *freq;
|
||||
devfreq->last_status.current_frequency = *freq;
|
||||
}
|
||||
rockchip_opp_dvfs_unlock(opp_info);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rkvenc_devfreq_get_dev_status(struct device *dev,
|
||||
struct devfreq_dev_status *stat)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rkvenc_devfreq_get_cur_freq(struct device *dev,
|
||||
unsigned long *freq)
|
||||
{
|
||||
struct mpp_dev *mpp = dev_get_drvdata(dev);
|
||||
struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
|
||||
|
||||
*freq = enc->core_current_rate_hz;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct devfreq_dev_profile rkvenc_devfreq_profile = {
|
||||
.target = rkvenc_devfreq_target,
|
||||
.get_dev_status = rkvenc_devfreq_get_dev_status,
|
||||
.get_cur_freq = rkvenc_devfreq_get_cur_freq,
|
||||
.is_cooling_device = true,
|
||||
};
|
||||
|
||||
static int devfreq_venc_ondemand_func(struct devfreq *df, unsigned long *freq)
|
||||
{
|
||||
struct rkvenc_dev *enc = df->data;
|
||||
|
||||
if (enc)
|
||||
*freq = enc->core_rate_hz;
|
||||
else
|
||||
*freq = df->previous_freq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int devfreq_venc_ondemand_handler(struct devfreq *devfreq,
|
||||
unsigned int event, void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct devfreq_governor devfreq_venc_ondemand = {
|
||||
.name = "venc_ondemand",
|
||||
.get_target_freq = devfreq_venc_ondemand_func,
|
||||
.event_handler = devfreq_venc_ondemand_handler,
|
||||
};
|
||||
|
||||
static int rk3588_venc_set_read_margin(struct device *dev,
|
||||
struct rockchip_opp_info *opp_info,
|
||||
u32 rm)
|
||||
@@ -2164,6 +2259,8 @@ static const struct of_device_id rockchip_rkvenc_of_match[] = {
|
||||
static struct monitor_dev_profile venc_mdevp = {
|
||||
.type = MONITOR_TYPE_DEV,
|
||||
.check_rate_volt = rockchip_monitor_check_rate_volt,
|
||||
.low_temp_adjust = rockchip_monitor_dev_low_temp_adjust,
|
||||
.high_temp_adjust = rockchip_monitor_dev_high_temp_adjust,
|
||||
};
|
||||
|
||||
static int rkvenc_devfreq_init(struct mpp_dev *mpp)
|
||||
@@ -2183,6 +2280,33 @@ static int rkvenc_devfreq_init(struct mpp_dev *mpp)
|
||||
dev_err(dev, "failed to init_opp_table\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
mutex_lock(&venc_governor_mutex);
|
||||
if (!venc_governor_count) {
|
||||
ret = devfreq_add_governor(&devfreq_venc_ondemand);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to add venc_ondemand governor\n");
|
||||
mutex_unlock(&venc_governor_mutex);
|
||||
goto governor_err;
|
||||
}
|
||||
}
|
||||
venc_governor_count++;
|
||||
mutex_unlock(&venc_governor_mutex);
|
||||
|
||||
rkvenc_devfreq_profile.initial_freq = clk_get_rate(clk_core);
|
||||
enc->core_rate_hz = rkvenc_devfreq_profile.initial_freq;
|
||||
enc->devfreq = devm_devfreq_add_device(dev,
|
||||
&rkvenc_devfreq_profile,
|
||||
"venc_ondemand", (void *)enc);
|
||||
if (IS_ERR(enc->devfreq)) {
|
||||
ret = PTR_ERR(enc->devfreq);
|
||||
enc->devfreq = NULL;
|
||||
goto devfreq_err;
|
||||
}
|
||||
|
||||
devfreq_register_opp_notifier(dev, enc->devfreq);
|
||||
|
||||
venc_mdevp.data = enc->devfreq;
|
||||
venc_mdevp.opp_info = opp_info;
|
||||
enc->mdev_info = rockchip_system_monitor_register(dev, &venc_mdevp);
|
||||
if (IS_ERR(enc->mdev_info)) {
|
||||
@@ -2190,6 +2314,24 @@ static int rkvenc_devfreq_init(struct mpp_dev *mpp)
|
||||
enc->mdev_info = NULL;
|
||||
}
|
||||
|
||||
enc->core_current_rate_hz = clk_get_rate(clk_core);
|
||||
enc->core_rate_hz = enc->core_current_rate_hz;
|
||||
if (enc->devfreq->suspend_freq)
|
||||
enc->devfreq->resume_freq = enc->core_current_rate_hz;
|
||||
enc->devfreq->last_status.current_frequency = enc->core_current_rate_hz;
|
||||
enc->devfreq->last_status.total_time = 1;
|
||||
enc->devfreq->last_status.busy_time = 1;
|
||||
|
||||
return 0;
|
||||
|
||||
devfreq_err:
|
||||
mutex_lock(&venc_governor_mutex);
|
||||
if (--venc_governor_count == 0)
|
||||
devfreq_remove_governor(&devfreq_venc_ondemand);
|
||||
mutex_unlock(&venc_governor_mutex);
|
||||
governor_err:
|
||||
dev_pm_opp_of_remove_table(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2201,6 +2343,12 @@ static int rkvenc_devfreq_remove(struct mpp_dev *mpp)
|
||||
rockchip_system_monitor_unregister(enc->mdev_info);
|
||||
enc->mdev_info = NULL;
|
||||
}
|
||||
if (enc->devfreq)
|
||||
devfreq_unregister_opp_notifier(mpp->dev, enc->devfreq);
|
||||
mutex_lock(&venc_governor_mutex);
|
||||
if (--venc_governor_count == 0)
|
||||
devfreq_remove_governor(&devfreq_venc_ondemand);
|
||||
mutex_unlock(&venc_governor_mutex);
|
||||
rockchip_uninit_opp_table(mpp->dev, &enc->opp_info);
|
||||
|
||||
return 0;
|
||||
@@ -2297,6 +2445,10 @@ static int rkvenc_reset(struct mpp_dev *mpp)
|
||||
|
||||
mpp_debug_enter();
|
||||
|
||||
#ifdef CONFIG_PM_DEVFREQ
|
||||
if (enc->devfreq)
|
||||
mutex_lock(&enc->devfreq->lock);
|
||||
#endif
|
||||
/* safe reset first*/
|
||||
ret = rkvenc_soft_reset(mpp);
|
||||
|
||||
@@ -2325,6 +2477,11 @@ static int rkvenc_reset(struct mpp_dev *mpp)
|
||||
|
||||
mpp_dbg_core("core %d reset idle %lx\n", mpp->core_id, queue->core_idle);
|
||||
|
||||
#ifdef CONFIG_PM_DEVFREQ
|
||||
if (enc->devfreq)
|
||||
mutex_unlock(&enc->devfreq->lock);
|
||||
#endif
|
||||
|
||||
mpp_debug_leave();
|
||||
|
||||
return 0;
|
||||
@@ -2358,6 +2515,27 @@ static int rkvenc_set_freq(struct mpp_dev *mpp, struct mpp_task *mpp_task)
|
||||
struct rkvenc_task *task = to_rkvenc_task(mpp_task);
|
||||
|
||||
mpp_clk_set_rate(&enc->aclk_info, task->clk_mode);
|
||||
|
||||
#ifdef CONFIG_PM_DEVFREQ
|
||||
if (enc->devfreq) {
|
||||
unsigned long core_rate_hz;
|
||||
|
||||
mutex_lock(&enc->devfreq->lock);
|
||||
core_rate_hz = mpp_get_clk_info_rate_hz(&enc->core_clk_info, task->clk_mode);
|
||||
if (enc->core_rate_hz != core_rate_hz) {
|
||||
enc->core_rate_hz = core_rate_hz;
|
||||
update_devfreq(enc->devfreq);
|
||||
} else {
|
||||
/*
|
||||
* Restore frequency when frequency is changed by
|
||||
* rkvenc_reduce_freq()
|
||||
*/
|
||||
clk_set_rate(enc->core_clk_info.clk, enc->core_current_rate_hz);
|
||||
}
|
||||
mutex_unlock(&enc->devfreq->lock);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
mpp_clk_set_rate(&enc->core_clk_info, task->clk_mode);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -41,3 +41,13 @@ void mpp_device_add_driver(void *dev, void *drv)
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL(mpp_device_add_driver);
|
||||
|
||||
struct dma_iommu_mapping *mpp_arm_iommu_get_mapping(struct device *dev)
|
||||
{
|
||||
#ifdef CONFIG_ARM_DMA_USE_IOMMU
|
||||
return dev->archdata.mapping;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
EXPORT_SYMBOL(mpp_arm_iommu_get_mapping);
|
||||
|
||||
@@ -10,10 +10,13 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_wakeup.h>
|
||||
|
||||
struct dma_iommu_mapping;
|
||||
|
||||
struct device_node *mpp_dev_of_node(struct device *dev);
|
||||
void mpp_pm_relax(struct device *dev);
|
||||
void mpp_pm_stay_awake(struct device *dev);
|
||||
int mpp_device_init_wakeup(struct device *dev, bool enable);
|
||||
void mpp_device_add_driver(void *dev, void *drv);
|
||||
struct dma_iommu_mapping *mpp_arm_iommu_get_mapping(struct device *dev);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user