mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
Merge commit 'c5179f362ee7db1a1771295badff67b014db03f5'
* commit 'c5179f362ee7db1a1771295badff67b014db03f5': (22 commits) tee: optee: interrupt an RPC depend on shutdown flag media: rockchip: isp: sync irq_ends mfd: rkx110_x120: cru: fix to get a avialble pll rate arm64: dts: rockchip: rk3562: adjust regulator-init-microvolt of vdd_cpu/vdd_logic for rk3562 boards arm64: dts: rockchip: rk3562: adjust low-temp-min-volt for cpu/dmc media: i2c: add sc830ai sensor driver dmaengine: pl330: Use tasklet_hi_schedule mtd: spinand: XINCUN: Support new device XCSP1AAPK arm64: dts: rockchip: rk3562-amp: change mcu ram address media: i2c: lt8668sx: add lt8668sx hdmi2csi driver video: rockchip: mpp: remove av1dec l2 cache ARM: rockchip: rv1106_pm: do wdt save/restore media: rockchip: isp: add buf cnt info to procfs media: rockchip: isp: fix wait timeout with thunderboot arm64: dts: rockchip: rk3528: Add thermal for macphy ARM: dts: rv1106: Add thermal for macphy net: phy: RK630: Add dynamically adjusting the configuration drm/bridge: dw-hdmi-qp: Fixes compilation errors when cec core is not compiled drm/bridge: synopsys: Fixes compilation errors when cec core is not compiled media: i2c: imx415 adapt sleep_wakeup ... Change-Id: I854d3c5a417d626ae2559264ce87a046dc65529a
This commit is contained in:
@@ -1359,6 +1359,7 @@
|
||||
nvmem-cells = <&macphy_txlevel>;
|
||||
nvmem-cell-names = "txlevel";
|
||||
bgs,increment = <2>;
|
||||
rockchip,thermal-zone = "soc-thermal";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -98,6 +98,8 @@ static void __iomem *firewall_syssram_base;
|
||||
static void __iomem *pmu_base;
|
||||
static void __iomem *nstimer_base;
|
||||
static void __iomem *stimer_base;
|
||||
static void __iomem *wdt_ns_base;
|
||||
static void __iomem *wdt_s_base;
|
||||
static void __iomem *mbox_base;
|
||||
static void __iomem *ddrc_base;
|
||||
static void __iomem *ioc_base[5];
|
||||
@@ -178,6 +180,10 @@ static struct reg_region vd_log_reg_rgns[] = {
|
||||
{ REG_REGION(0x304, 0x32c, 4, &pericru_base, WMSK_VAL)},
|
||||
{ REG_REGION(0x800, 0x81c, 4, &pericru_base, WMSK_VAL)},
|
||||
|
||||
/* peri_grf */
|
||||
{ REG_REGION(0x000, 0x004, 4, &perigrf_base, WMSK_VAL)},
|
||||
{ REG_REGION(0x090, 0x094, 4, &perigrf_base, WMSK_VAL)},
|
||||
|
||||
/* peri_sgrf */
|
||||
{ REG_REGION(0x004, 0x014, 4, &perisgrf_base, 0)},
|
||||
{ REG_REGION(0x000, 0x000, 4, &perisgrf_base, 0)},
|
||||
@@ -284,6 +290,14 @@ static struct reg_region vd_log_reg_rgns[] = {
|
||||
{ REG_REGION(0x10, 0x10, 4, &stimer_base, 0)},
|
||||
{ REG_REGION(0x20, 0x24, 4, &stimer_base, 0)},
|
||||
{ REG_REGION(0x30, 0x30, 4, &stimer_base, 0)},
|
||||
|
||||
/* wdt_ns */
|
||||
{ REG_REGION(0x04, 0x04, 4, &wdt_ns_base, 0)},
|
||||
{ REG_REGION(0x00, 0x00, 4, &wdt_ns_base, 0)},
|
||||
|
||||
/* wdt_s */
|
||||
{ REG_REGION(0x04, 0x04, 4, &wdt_s_base, 0)},
|
||||
{ REG_REGION(0x00, 0x00, 4, &wdt_s_base, 0)},
|
||||
};
|
||||
|
||||
static int is_rv1103, is_rv1106;
|
||||
@@ -1040,6 +1054,15 @@ static void vd_log_regs_restore(void)
|
||||
writel_relaxed(WITH_16BITS_WMSK(cru_mode), cru_base + 0x280);
|
||||
|
||||
gic400_restore();
|
||||
|
||||
writel_relaxed(0xffff0000, pmugrf_base + RV1106_PMUGRF_SOC_CON(4));
|
||||
writel_relaxed(0xffff0000, pmugrf_base + RV1106_PMUGRF_SOC_CON(5));
|
||||
|
||||
if (readl_relaxed(wdt_ns_base + RV1106_WDT_CR) & 0x1)
|
||||
writel_relaxed(0x76, wdt_ns_base + RV1106_WDT_CRR);
|
||||
|
||||
if (readl_relaxed(wdt_s_base + RV1106_WDT_CR) & 0x1)
|
||||
writel_relaxed(0x76, wdt_s_base + RV1106_WDT_CRR);
|
||||
}
|
||||
|
||||
static void rkpm_reg_rgns_init(void)
|
||||
@@ -1182,6 +1205,9 @@ static int __init rv1106_suspend_init(struct device_node *np)
|
||||
nstimer_base = dev_reg_base + RV1106_NSTIMER_OFFSET;
|
||||
stimer_base = dev_reg_base + RV1106_STIMER_OFFSET;
|
||||
|
||||
wdt_ns_base = dev_reg_base + RV1106_WDTNS_OFFSET;
|
||||
wdt_s_base = dev_reg_base + RV1106_WDTS_OFFSET;
|
||||
|
||||
pmu_base = dev_reg_base + RV1106_PMU_OFFSET;
|
||||
uartdbg_base = dev_reg_base + RV1106_UART2_OFFSET;
|
||||
pmupvtm_base = dev_reg_base + RV1106_PMUPVTM_OFFSET;
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
|
||||
#define RV1106_NSTIMER_OFFSET 0x580000
|
||||
#define RV1106_STIMER_OFFSET 0x590000
|
||||
#define RV1106_WDTNS_OFFSET 0x5a0000
|
||||
#define RV1106_WDTS_OFFSET 0x5b0000
|
||||
#define RV1106_MBOX_OFFSET 0x5c0000
|
||||
#define RV1106_PMUSRAM_OFFSET 0x670000
|
||||
#define RV1106_DDRC_OFFSET 0x800000
|
||||
@@ -185,6 +187,14 @@
|
||||
#define RV1106_PMU_INFO_TX_CON 0x150
|
||||
#define RV1106_PMU_SYS_REG(i) (0x1c0 + (i) * 4)
|
||||
|
||||
/* wdt */
|
||||
#define RV1106_WDT_CR 0x0
|
||||
#define RV1106_WDT_TORR 0x4
|
||||
#define RV1106_WDT_CCVR 0x8
|
||||
#define RV1106_WDT_CRR 0xc
|
||||
#define RV1106_WDT_STAT 0x10
|
||||
#define RV1106_WDT_EOI 0x14
|
||||
|
||||
#define PMU_SUSPEND_MAGIC 0x02468ace
|
||||
#define PMU_RESUME_MAGIC 0x13579bdf
|
||||
|
||||
|
||||
@@ -2095,6 +2095,7 @@
|
||||
pinctrl-0 = <&fephym0_led_link &fephym0_led_spd>;
|
||||
nvmem-cells = <&macphy_txlevel>;
|
||||
nvmem-cell-names = "txlevel";
|
||||
rockchip,thermal-zone = "soc-thermal";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -29,7 +29,13 @@
|
||||
|
||||
/* remote amp core address */
|
||||
amp_shmem_reserved: amp-shmem@7800000 {
|
||||
reg = <0x0 0x7800000 0x0 0x400000>;
|
||||
reg = <0x0 0x7800000 0x0 0x300000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
/* mcu address */
|
||||
mcu_reserved: mcu@7b00000 {
|
||||
reg = <0x0 0x7b00000 0x0 0x100000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
@@ -43,13 +49,6 @@
|
||||
reg = <0x0 0x08000000 0x0 0x100000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
/* mcu address */
|
||||
mcu_reserved: mcu@8200000 {
|
||||
reg = <0x0 0x8200000 0x0 0x100000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
rpmsg: rpmsg@7c00000 {
|
||||
|
||||
@@ -167,6 +167,8 @@
|
||||
};
|
||||
|
||||
&cpu0_opp_table {
|
||||
rockchip,low-temp-min-volt = <1000000>;
|
||||
|
||||
opp-408000000 {
|
||||
/delete-property/ opp-suspend;
|
||||
};
|
||||
@@ -680,7 +682,7 @@
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <800000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-init-microvolt = <900000>;
|
||||
regulator-init-microvolt = <950000>;
|
||||
regulator-ramp-delay = <6001>;
|
||||
regulator-initial-mode = <0x2>;
|
||||
regulator-name = "vdd_logic";
|
||||
@@ -695,7 +697,7 @@
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <825000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-init-microvolt = <900000>;
|
||||
regulator-init-microvolt = <1000000>;
|
||||
regulator-ramp-delay = <6001>;
|
||||
regulator-initial-mode = <0x2>;
|
||||
regulator-name = "vdd_cpu";
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-init-microvolt = <900000>;
|
||||
regulator-init-microvolt = <950000>;
|
||||
regulator-ramp-delay = <6001>;
|
||||
regulator-initial-mode = <0x2>;
|
||||
regulator-name = "vdd_logic";
|
||||
@@ -90,7 +90,7 @@
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-init-microvolt = <900000>;
|
||||
regulator-init-microvolt = <1050000>;
|
||||
regulator-ramp-delay = <6001>;
|
||||
regulator-initial-mode = <0x2>;
|
||||
regulator-name = "vdd_cpu";
|
||||
|
||||
@@ -601,7 +601,7 @@
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-init-microvolt = <900000>;
|
||||
regulator-init-microvolt = <950000>;
|
||||
regulator-ramp-delay = <6001>;
|
||||
regulator-initial-mode = <0x2>;
|
||||
regulator-name = "vdd_logic";
|
||||
@@ -616,7 +616,7 @@
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-init-microvolt = <900000>;
|
||||
regulator-init-microvolt = <1050000>;
|
||||
regulator-ramp-delay = <6001>;
|
||||
regulator-initial-mode = <0x2>;
|
||||
regulator-name = "vdd_cpu";
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-init-microvolt = <900000>;
|
||||
regulator-init-microvolt = <950000>;
|
||||
regulator-ramp-delay = <6001>;
|
||||
regulator-initial-mode = <0x2>;
|
||||
regulator-name = "vdd_logic";
|
||||
@@ -87,7 +87,7 @@
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-init-microvolt = <900000>;
|
||||
regulator-init-microvolt = <1050000>;
|
||||
regulator-ramp-delay = <6001>;
|
||||
regulator-initial-mode = <0x2>;
|
||||
regulator-name = "vdd_cpu";
|
||||
|
||||
@@ -273,7 +273,7 @@
|
||||
rockchip,grf = <&sys_grf>;
|
||||
rockchip,temp-hysteresis = <5000>;
|
||||
rockchip,low-temp = <10000>;
|
||||
rockchip,low-temp-min-volt = <925000>;
|
||||
rockchip,low-temp-min-volt = <1050000>;
|
||||
|
||||
opp-408000000 {
|
||||
opp-hz = /bits/ 64 <408000000>;
|
||||
@@ -501,7 +501,7 @@
|
||||
|
||||
rockchip,temp-hysteresis = <5000>;
|
||||
rockchip,low-temp = <10000>;
|
||||
rockchip,low-temp-min-volt = <900000>;
|
||||
rockchip,low-temp-min-volt = <950000>;
|
||||
|
||||
rockchip,leakage-voltage-sel = <
|
||||
1 15 0
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-init-microvolt = <900000>;
|
||||
regulator-init-microvolt = <950000>;
|
||||
regulator-ramp-delay = <6001>;
|
||||
regulator-initial-mode = <0x2>;
|
||||
regulator-name = "vdd_logic";
|
||||
@@ -194,7 +194,7 @@
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <500000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-init-microvolt = <900000>;
|
||||
regulator-init-microvolt = <1050000>;
|
||||
regulator-ramp-delay = <6001>;
|
||||
regulator-initial-mode = <0x2>;
|
||||
regulator-name = "vdd_cpu";
|
||||
|
||||
@@ -1758,7 +1758,7 @@ static void dma_pl330_rqcb(struct dma_pl330_desc *desc, enum pl330_op_err err)
|
||||
|
||||
spin_unlock_irqrestore(&pch->lock, flags);
|
||||
|
||||
tasklet_schedule(&pch->task);
|
||||
tasklet_hi_schedule(&pch->task);
|
||||
}
|
||||
|
||||
static void pl330_dotask(struct tasklet_struct *t)
|
||||
|
||||
@@ -3276,8 +3276,10 @@ void dw_hdmi_qp_cec_set_hpd(struct dw_hdmi_qp *hdmi, bool plug_in, bool change)
|
||||
CEC_PHYS_ADDR_INVALID);
|
||||
|
||||
if (hdmi->bridge.dev) {
|
||||
#if IS_REACHABLE(CONFIG_DRM_DW_HDMI_CEC)
|
||||
if (change && hdmi->cec_adap && hdmi->cec_adap->devnode.registered)
|
||||
cec_queue_pin_hpd_event(hdmi->cec_adap, plug_in, ktime_get());
|
||||
#endif
|
||||
drm_bridge_hpd_notify(&hdmi->bridge, status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,10 +433,12 @@ static void repo_hpd_event(struct work_struct *p_work)
|
||||
if (change) {
|
||||
if (hdmi->plat_data->set_ddc_io)
|
||||
hdmi->plat_data->set_ddc_io(data, hdmi->hpd_state);
|
||||
#if IS_REACHABLE(CONFIG_DRM_DW_HDMI_CEC)
|
||||
if (hdmi->cec_adap->devnode.registered)
|
||||
cec_queue_pin_hpd_event(hdmi->cec_adap,
|
||||
hdmi->hpd_state,
|
||||
ktime_get());
|
||||
#endif
|
||||
}
|
||||
drm_bridge_hpd_notify(&hdmi->bridge, status);
|
||||
}
|
||||
|
||||
@@ -1962,6 +1962,16 @@ config VIDEO_SC5336
|
||||
This is a Video4Linux2 sensor driver for the SmartSens
|
||||
SC5336 camera.
|
||||
|
||||
config VIDEO_SC830AI
|
||||
tristate "SmartSens SC830AI sensor support"
|
||||
depends on I2C && VIDEO_DEV
|
||||
select MEDIA_CONTROLLER
|
||||
select VIDEO_V4L2_SUBDEV_API
|
||||
select V4L2_FWNODE
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for the SmartSens
|
||||
SC830AI camera.
|
||||
|
||||
config VIDEO_SC850SL
|
||||
tristate "SmartSens SC850SL sensor support"
|
||||
depends on I2C && VIDEO_DEV
|
||||
@@ -2605,6 +2615,19 @@ config VIDEO_LT8619C
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called lt8619c.
|
||||
|
||||
config VIDEO_LT8668SX
|
||||
tristate "Lontium LT8668SX decoder"
|
||||
depends on VIDEO_DEV && I2C
|
||||
select HDMI
|
||||
select MEDIA_CONTROLLER
|
||||
select VIDEO_V4L2_SUBDEV_API
|
||||
select V4L2_FWNODE
|
||||
help
|
||||
Support for the Lontium LT8668SX series type-c/hdmi to MIPI CSI-2 bridge.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called lt8668sx.
|
||||
|
||||
config VIDEO_MAX9286
|
||||
tristate "Maxim MAX9286 GMSL deserializer support"
|
||||
depends on I2C && I2C_MUX
|
||||
|
||||
@@ -116,6 +116,7 @@ obj-$(CONFIG_VIDEO_LT6911UXE) += lt6911uxe.o
|
||||
obj-$(CONFIG_VIDEO_LT7911D) += lt7911d.o
|
||||
obj-$(CONFIG_VIDEO_LT7911UXC) += lt7911uxc.o
|
||||
obj-$(CONFIG_VIDEO_LT8619C) += lt8619c.o
|
||||
obj-$(CONFIG_VIDEO_LT8668SX) += lt8668sx.o
|
||||
obj-$(CONFIG_VIDEO_M52790) += m52790.o
|
||||
obj-$(CONFIG_VIDEO_M5MOLS) += m5mols/
|
||||
obj-$(CONFIG_VIDEO_MAX9271_LIB) += max9271.o
|
||||
@@ -245,6 +246,7 @@ obj-$(CONFIG_VIDEO_SC500AI) += sc500ai.o
|
||||
obj-$(CONFIG_VIDEO_SC501AI) += sc501ai.o
|
||||
obj-$(CONFIG_VIDEO_SC530AI) += sc530ai.o
|
||||
obj-$(CONFIG_VIDEO_SC5336) += sc5336.o
|
||||
obj-$(CONFIG_VIDEO_SC830AI) += sc830ai.o
|
||||
obj-$(CONFIG_VIDEO_SC850SL) += sc850sl.o
|
||||
obj-$(CONFIG_VIDEO_SENSOR_ADAPTER) += sensor_adapter.o
|
||||
obj-$(CONFIG_VIDEO_SGM3784) += sgm3784.o
|
||||
|
||||
@@ -53,6 +53,8 @@
|
||||
#include <media/v4l2-fwnode.h>
|
||||
#include <linux/of_graph.h>
|
||||
#include "../platform/rockchip/isp/rkisp_tb_helper.h"
|
||||
#include "cam-tb-setup.h"
|
||||
#include "cam-sleep-wakeup.h"
|
||||
|
||||
#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x08)
|
||||
|
||||
@@ -242,6 +244,7 @@ struct imx415 {
|
||||
bool has_init_exp;
|
||||
struct preisp_hdrae_exp_s init_hdrae_exp;
|
||||
struct v4l2_fwnode_endpoint bus_cfg;
|
||||
struct cam_sw_info *cam_sw_inf;
|
||||
};
|
||||
|
||||
static struct rkmodule_csi_dphy_param dcphy_param = {
|
||||
@@ -2426,11 +2429,6 @@ int __imx415_power_on(struct imx415 *imx415)
|
||||
}
|
||||
|
||||
if (!imx415->is_thunderboot) {
|
||||
ret = regulator_bulk_enable(IMX415_NUM_SUPPLIES, imx415->supplies);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to enable regulators\n");
|
||||
goto err_pinctrl;
|
||||
}
|
||||
if (!IS_ERR(imx415->power_gpio))
|
||||
gpiod_direction_output(imx415->power_gpio, 1);
|
||||
/* At least 500ns between power raising and XCLR */
|
||||
@@ -2454,18 +2452,28 @@ int __imx415_power_on(struct imx415 *imx415)
|
||||
goto err_clk;
|
||||
}
|
||||
|
||||
cam_sw_regulator_bulk_init(imx415->cam_sw_inf, IMX415_NUM_SUPPLIES, imx415->supplies);
|
||||
|
||||
if (imx415->is_thunderboot)
|
||||
return 0;
|
||||
|
||||
/* At least 20us between XCLR and I2C communication */
|
||||
if (!imx415->is_thunderboot)
|
||||
usleep_range(20*1000, 30*1000);
|
||||
usleep_range(20*1000, 30*1000);
|
||||
|
||||
ret = regulator_bulk_enable(IMX415_NUM_SUPPLIES, imx415->supplies);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to enable regulators\n");
|
||||
goto err_pinctrl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_pinctrl:
|
||||
clk_disable_unprepare(imx415->xvclk);
|
||||
|
||||
err_clk:
|
||||
if (!IS_ERR(imx415->reset_gpio))
|
||||
gpiod_direction_output(imx415->reset_gpio, 1);
|
||||
regulator_bulk_disable(IMX415_NUM_SUPPLIES, imx415->supplies);
|
||||
|
||||
err_pinctrl:
|
||||
if (!IS_ERR_OR_NULL(imx415->pins_sleep))
|
||||
pinctrl_select_state(imx415->pinctrl, imx415->pins_sleep);
|
||||
|
||||
@@ -2500,6 +2508,51 @@ static void __imx415_power_off(struct imx415 *imx415)
|
||||
regulator_bulk_disable(IMX415_NUM_SUPPLIES, imx415->supplies);
|
||||
}
|
||||
|
||||
#if IS_REACHABLE(CONFIG_VIDEO_CAM_SLEEP_WAKEUP)
|
||||
static int __maybe_unused imx415_resume(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct imx415 *imx415 = to_imx415(sd);
|
||||
|
||||
cam_sw_prepare_wakeup(imx415->cam_sw_inf, dev);
|
||||
|
||||
usleep_range(4000, 5000);
|
||||
cam_sw_write_array(imx415->cam_sw_inf);
|
||||
|
||||
if (__v4l2_ctrl_handler_setup(&imx415->ctrl_handler))
|
||||
dev_err(dev, "__v4l2_ctrl_handler_setup fail!");
|
||||
|
||||
if (imx415->has_init_exp && imx415->cur_mode != NO_HDR) { // hdr mode
|
||||
ret = imx415_ioctl(&imx415->subdev, PREISP_CMD_SET_HDRAE_EXP,
|
||||
&imx415->cam_sw_inf->hdr_ae);
|
||||
if (ret) {
|
||||
dev_err(&imx415->client->dev, "set exp fail in hdr mode\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused imx415_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct imx415 *imx415 = to_imx415(sd);
|
||||
|
||||
cam_sw_write_array_cb_init(imx415->cam_sw_inf, client,
|
||||
(void *)imx415->cur_mode->reg_list,
|
||||
(sensor_write_array)imx415_write_array);
|
||||
cam_sw_prepare_sleep(imx415->cam_sw_inf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define imx415_resume NULL
|
||||
#define imx415_suspend NULL
|
||||
#endif
|
||||
|
||||
static int __maybe_unused imx415_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
@@ -2605,6 +2658,7 @@ static int imx415_get_selection(struct v4l2_subdev *sd,
|
||||
static const struct dev_pm_ops imx415_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(imx415_runtime_suspend,
|
||||
imx415_runtime_resume, NULL)
|
||||
SET_LATE_SYSTEM_SLEEP_PM_OPS(imx415_suspend, imx415_resume)
|
||||
};
|
||||
|
||||
#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
|
||||
@@ -3018,6 +3072,14 @@ static int imx415_probe(struct i2c_client *client,
|
||||
goto err_power_off;
|
||||
#endif
|
||||
|
||||
if (!imx415->cam_sw_inf) {
|
||||
imx415->cam_sw_inf = cam_sw_init();
|
||||
cam_sw_clk_init(imx415->cam_sw_inf, imx415->xvclk, imx415->cur_mode->xvclk);
|
||||
cam_sw_reset_pin_init(imx415->cam_sw_inf, imx415->reset_gpio, 1);
|
||||
if (!IS_ERR(imx415->power_gpio))
|
||||
cam_sw_pwdn_pin_init(imx415->cam_sw_inf, imx415->power_gpio, 0);
|
||||
}
|
||||
|
||||
memset(facing, 0, sizeof(facing));
|
||||
if (strcmp(imx415->module_facing, "back") == 0)
|
||||
facing[0] = 'b';
|
||||
@@ -3065,6 +3127,8 @@ static void imx415_remove(struct i2c_client *client)
|
||||
v4l2_ctrl_handler_free(&imx415->ctrl_handler);
|
||||
mutex_destroy(&imx415->mutex);
|
||||
|
||||
cam_sw_deinit(imx415->cam_sw_inf);
|
||||
|
||||
pm_runtime_disable(&client->dev);
|
||||
if (!pm_runtime_status_suspended(&client->dev))
|
||||
__imx415_power_off(imx415);
|
||||
|
||||
1794
drivers/media/i2c/lt8668sx.c
Normal file
1794
drivers/media/i2c/lt8668sx.c
Normal file
File diff suppressed because it is too large
Load Diff
1930
drivers/media/i2c/sc830ai.c
Normal file
1930
drivers/media/i2c/sc830ai.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -81,6 +81,7 @@ MODULE_PARM_DESC(low_latency, "low_latency en(0-1)");
|
||||
#define NO_LOCK_CFG_RETRY_TIME 300
|
||||
#define WAIT_LOCK_STABLE_TIME 20
|
||||
#define WAIT_AVI_PKT_TIME 300
|
||||
#define BIG_CPU_PHY_ID 5
|
||||
|
||||
#define is_validfs(x) (x == 32000 || \
|
||||
x == 44100 || \
|
||||
@@ -4589,9 +4590,9 @@ static int hdmirx_probe(struct platform_device *pdev)
|
||||
struct v4l2_device *v4l2_dev;
|
||||
struct v4l2_ctrl_handler *hdl;
|
||||
struct resource *res;
|
||||
int ret, irq, cpu_aff;
|
||||
struct hdmirx_cec_data cec_data;
|
||||
struct cpumask cpumask;
|
||||
int ret, irq, cpu_aff, phy_cpuid, i;
|
||||
|
||||
hdmirx_dev = devm_kzalloc(dev, sizeof(*hdmirx_dev), GFP_KERNEL);
|
||||
if (!hdmirx_dev)
|
||||
@@ -4618,12 +4619,22 @@ static int hdmirx_probe(struct platform_device *pdev)
|
||||
* in order to quickly respond to FIQ and prevent them from affecting
|
||||
* each other.
|
||||
*/
|
||||
if (sip_cpu_logical_map_mpidr(0) == 0) {
|
||||
cpu_aff = sip_cpu_logical_map_mpidr(5);
|
||||
hdmirx_dev->bound_cpu = 5;
|
||||
} else {
|
||||
cpu_aff = sip_cpu_logical_map_mpidr(1);
|
||||
hdmirx_dev->bound_cpu = 1;
|
||||
for (i = 0; i < 8; i++) {
|
||||
cpu_aff = sip_cpu_logical_map_mpidr(i);
|
||||
phy_cpuid = (cpu_aff >> 8) & 0xf;
|
||||
if (phy_cpuid == BIG_CPU_PHY_ID) {
|
||||
hdmirx_dev->bound_cpu = i;
|
||||
hdmirx_dev->phy_cpuid = phy_cpuid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hdmirx_dev->phy_cpuid) {
|
||||
dev_info(dev, "%s: Failed to get phy_cpuid, use default BIG_CPU_PHY_ID!\n",
|
||||
__func__);
|
||||
cpu_aff = BIG_CPU_PHY_ID << 8;
|
||||
hdmirx_dev->bound_cpu = BIG_CPU_PHY_ID;
|
||||
hdmirx_dev->phy_cpuid = BIG_CPU_PHY_ID;
|
||||
}
|
||||
|
||||
sip_fiq_control(RK_SIP_FIQ_CTRL_SET_AFF, RK_IRQ_HDMIRX_HDMI, cpu_aff);
|
||||
|
||||
@@ -475,6 +475,23 @@ void rkisp_stream_buf_done_early(struct rkisp_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
int rkisp_stream_buf_cnt(struct rkisp_stream *stream)
|
||||
{
|
||||
unsigned long lock_flags = 0;
|
||||
struct rkisp_buffer *buf, *tmp;
|
||||
int cnt = 0;
|
||||
|
||||
spin_lock_irqsave(&stream->vbq_lock, lock_flags);
|
||||
list_for_each_entry_safe(buf, tmp, &stream->buf_queue, queue)
|
||||
cnt++;
|
||||
if (stream->curr_buf)
|
||||
cnt++;
|
||||
if (stream->next_buf && stream->next_buf != stream->curr_buf)
|
||||
cnt++;
|
||||
spin_unlock_irqrestore(&stream->vbq_lock, lock_flags);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
struct stream_config rkisp_mp_stream_config = {
|
||||
/* constraints */
|
||||
.max_rsz_width = STREAM_MAX_MP_RSZ_OUTPUT_WIDTH,
|
||||
|
||||
@@ -342,4 +342,5 @@ int rkisp_fop_release(struct file *file);
|
||||
int rkisp_get_tb_stream_info(struct rkisp_stream *stream,
|
||||
struct rkisp_tb_stream_info *info);
|
||||
int rkisp_free_tb_stream_buf(struct rkisp_stream *stream);
|
||||
int rkisp_stream_buf_cnt(struct rkisp_stream *stream);
|
||||
#endif /* _RKISP_PATH_VIDEO_H */
|
||||
|
||||
@@ -833,6 +833,7 @@ static int isp_show(struct seq_file *p, void *v)
|
||||
struct rkisp_device *dev = p->private;
|
||||
struct rkisp_isp_subdev *sdev = &dev->isp_sdev;
|
||||
struct rkisp_sensor_info *sensor = dev->active_sensor;
|
||||
struct rkisp_stream *stream;
|
||||
u32 val = 0;
|
||||
|
||||
seq_printf(p, "%-10s Version:v%02x.%02x.%02x\n",
|
||||
@@ -864,7 +865,9 @@ static int isp_show(struct seq_file *p, void *v)
|
||||
return 0;
|
||||
|
||||
if (IS_HDR_RDBK(dev->hdr.op_mode)) {
|
||||
seq_printf(p, "%-10s mode:frame%d (frame:%d rate:%dms %s time:%dms frameloss:%d) cnt(total:%d X1:%d X2:%d X3:%d)\n",
|
||||
stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD2];
|
||||
seq_printf(p, "%-10s mode:frame%d (frame:%d rate:%dms state:%s time:%dms frameloss:%d)"
|
||||
" cnt(total:%d X1:%d X2:%d X3:%d) rd_bufcnt:%d\n",
|
||||
"Isp Read",
|
||||
dev->rd_mode - 3,
|
||||
dev->dmarx_dev.cur_frame.id,
|
||||
@@ -875,12 +878,13 @@ static int isp_show(struct seq_file *p, void *v)
|
||||
dev->rdbk_cnt,
|
||||
dev->rdbk_cnt_x1,
|
||||
dev->rdbk_cnt_x2,
|
||||
dev->rdbk_cnt_x3);
|
||||
dev->rdbk_cnt_x3,
|
||||
rkisp_stream_buf_cnt(stream));
|
||||
seq_printf(p, "\t hw link:%d idle:%d vir(mode:%d index:%d)\n",
|
||||
dev->hw_dev->dev_link_num, dev->hw_dev->is_idle,
|
||||
dev->multi_mode, dev->multi_index);
|
||||
} else {
|
||||
seq_printf(p, "%-10s frame:%d %s time:%dms v-blank:%dus\n",
|
||||
seq_printf(p, "%-10s frame:%d state:%s time:%dms v-blank:%dus\n",
|
||||
"Isp online",
|
||||
sdev->dbg.id,
|
||||
(dev->isp_state & ISP_FRAME_END) ? "idle" : "working",
|
||||
@@ -899,11 +903,11 @@ static int isp_show(struct seq_file *p, void *v)
|
||||
dev->br_dev.dbg.interval / 1000 / 1000,
|
||||
dev->br_dev.dbg.frameloss);
|
||||
for (val = 0; val < RKISP_MAX_STREAM; val++) {
|
||||
struct rkisp_stream *stream = &dev->cap_dev.stream[val];
|
||||
|
||||
stream = &dev->cap_dev.stream[val];
|
||||
if (!stream->streaming)
|
||||
continue;
|
||||
seq_printf(p, "%-10s %s Format:%c%c%c%c Size:%dx%d Dcrop(%d,%d|%dx%d) (frame:%d rate:%dms delay:%dms frameloss:%d)\n",
|
||||
seq_printf(p, "%-10s %s Format:%c%c%c%c Size:%dx%d Dcrop(%d,%d|%dx%d)"
|
||||
" (frame:%d rate:%dms delay:%dms frameloss:%d bufcnt:%d)\n",
|
||||
"Output",
|
||||
stream->vnode.vdev.name,
|
||||
stream->out_fmt.pixelformat,
|
||||
@@ -919,7 +923,8 @@ static int isp_show(struct seq_file *p, void *v)
|
||||
stream->dbg.id,
|
||||
stream->dbg.interval / 1000 / 1000,
|
||||
stream->dbg.delay / 1000 / 1000,
|
||||
stream->dbg.frameloss);
|
||||
stream->dbg.frameloss,
|
||||
rkisp_stream_buf_cnt(stream));
|
||||
}
|
||||
|
||||
switch (dev->isp_ver) {
|
||||
|
||||
@@ -1059,8 +1059,10 @@ static void rkisp_rdbk_work(struct work_struct *work)
|
||||
|
||||
void rkisp_check_idle(struct rkisp_device *dev, u32 irq)
|
||||
{
|
||||
unsigned long lock_flags = 0;
|
||||
u32 val = 0;
|
||||
|
||||
spin_lock_irqsave(&dev->hw_dev->rdbk_lock, lock_flags);
|
||||
dev->irq_ends |= (irq & dev->irq_ends_mask);
|
||||
v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev,
|
||||
"%s irq:0x%x ends:0x%x mask:0x%x\n",
|
||||
@@ -1072,8 +1074,11 @@ void rkisp_check_idle(struct rkisp_device *dev, u32 irq)
|
||||
complete(&dev->hw_dev->monitor.cmpl);
|
||||
}
|
||||
if ((dev->irq_ends & dev->irq_ends_mask) != dev->irq_ends_mask ||
|
||||
!IS_HDR_RDBK(dev->rd_mode))
|
||||
!IS_HDR_RDBK(dev->rd_mode)) {
|
||||
spin_unlock_irqrestore(&dev->hw_dev->rdbk_lock, lock_flags);
|
||||
return;
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->hw_dev->rdbk_lock, lock_flags);
|
||||
|
||||
if (dev->sw_rd_cnt)
|
||||
goto end;
|
||||
@@ -1920,6 +1925,9 @@ static void rkisp_start_3a_run(struct rkisp_device *dev)
|
||||
return;
|
||||
|
||||
v4l2_event_queue(vdev, &ev);
|
||||
/* thunderboot no need to wait aiq first param */
|
||||
if (dev->is_pre_on)
|
||||
return;
|
||||
/* rk3326/px30 require first params queued before
|
||||
* rkisp_params_configure_isp() called
|
||||
*/
|
||||
|
||||
@@ -263,6 +263,7 @@ static HAL_Status RKX11x_HAL_CRU_ClkSetFreq(struct hwclk *hw, uint32_t clockName
|
||||
uint32_t pll;
|
||||
uint8_t overMax = 0;
|
||||
HAL_Status ret = HAL_OK;
|
||||
int i;
|
||||
|
||||
if (clockName == RKX110_CLK_D_DSI_0_PATTERN_GEN ||
|
||||
clockName == RKX110_CLK_D_DSI_1_PATTERN_GEN) {
|
||||
@@ -326,12 +327,21 @@ static HAL_Status RKX11x_HAL_CRU_ClkSetFreq(struct hwclk *hw, uint32_t clockName
|
||||
|
||||
/* PLL change closest new rate <= 1200M if need */
|
||||
if (!pRate) {
|
||||
pRate = (_MHZ(1200) / rate) * rate;
|
||||
}
|
||||
|
||||
ret = RKX11x_HAL_CRU_ClkSetFreq(hw, pll, pRate);
|
||||
if (ret != HAL_OK) {
|
||||
return ret;
|
||||
if (!rate || rate > _MHZ(1200))
|
||||
return HAL_ERROR;
|
||||
for (i = _MHZ(1200) / rate; i > _MHZ(24) / rate; i--) {
|
||||
pRate = i * rate;
|
||||
ret = RKX11x_HAL_CRU_ClkSetFreq(hw, pll, pRate);
|
||||
if (ret == HAL_OK)
|
||||
break;
|
||||
}
|
||||
if (ret != HAL_OK)
|
||||
return ret;
|
||||
} else {
|
||||
ret = RKX11x_HAL_CRU_ClkSetFreq(hw, pll, pRate);
|
||||
if (ret != HAL_OK) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* if success, continue to set divider */
|
||||
|
||||
@@ -304,6 +304,7 @@ static HAL_Status RKX11x_HAL_CRU_ClkSetFreq(struct hwclk *hw, uint32_t clockName
|
||||
uint32_t pll;
|
||||
uint8_t overMax = 0;
|
||||
HAL_Status ret = HAL_OK;
|
||||
int i;
|
||||
|
||||
if (clockName == RKX110_CLK_D_DSI_0_PATTERN_GEN) {
|
||||
clockName = RKX111_CPS_DCLK_D_DSI_0_REC;
|
||||
@@ -371,12 +372,21 @@ static HAL_Status RKX11x_HAL_CRU_ClkSetFreq(struct hwclk *hw, uint32_t clockName
|
||||
|
||||
/* PLL change closest new rate <= 1200M if need */
|
||||
if (!pRate) {
|
||||
pRate = (_MHZ(1200) / rate) * rate;
|
||||
}
|
||||
|
||||
ret = RKX11x_HAL_CRU_ClkSetFreq(hw, pll, pRate);
|
||||
if (ret != HAL_OK) {
|
||||
return ret;
|
||||
if (!rate || rate > _MHZ(1200))
|
||||
return HAL_ERROR;
|
||||
for (i = _MHZ(1200) / rate; i > _MHZ(24) / rate; i--) {
|
||||
pRate = i * rate;
|
||||
ret = RKX11x_HAL_CRU_ClkSetFreq(hw, pll, pRate);
|
||||
if (ret == HAL_OK)
|
||||
break;
|
||||
}
|
||||
if (ret != HAL_OK)
|
||||
return ret;
|
||||
} else {
|
||||
ret = RKX11x_HAL_CRU_ClkSetFreq(hw, pll, pRate);
|
||||
if (ret != HAL_OK) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* if success, continue to set divider */
|
||||
|
||||
@@ -252,6 +252,7 @@ static HAL_Status RKX12x_HAL_CRU_ClkSetFreq(struct hwclk *hw, uint32_t clockName
|
||||
uint32_t pll;
|
||||
uint8_t overMax;
|
||||
HAL_Status ret = HAL_OK;
|
||||
int i;
|
||||
|
||||
switch (clockName) {
|
||||
case RKX120_CPS_PLL_TXPLL:
|
||||
@@ -298,12 +299,21 @@ static HAL_Status RKX12x_HAL_CRU_ClkSetFreq(struct hwclk *hw, uint32_t clockName
|
||||
|
||||
/* PLL change closest new rate <= 1200M if need */
|
||||
if (!pRate) {
|
||||
pRate = (_MHZ(1200) / rate) * rate;
|
||||
}
|
||||
|
||||
ret = RKX12x_HAL_CRU_ClkSetFreq(hw, pll, pRate);
|
||||
if (ret != HAL_OK) {
|
||||
return ret;
|
||||
if (!rate || rate > _MHZ(1200))
|
||||
return HAL_ERROR;
|
||||
for (i = _MHZ(1200) / rate; i > _MHZ(24) / rate; i--) {
|
||||
pRate = i * rate;
|
||||
ret = RKX12x_HAL_CRU_ClkSetFreq(hw, pll, pRate);
|
||||
if (ret == HAL_OK)
|
||||
break;
|
||||
}
|
||||
if (ret != HAL_OK)
|
||||
return ret;
|
||||
} else {
|
||||
ret = RKX12x_HAL_CRU_ClkSetFreq(hw, pll, pRate);
|
||||
if (ret != HAL_OK) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* if success, continue to set divider */
|
||||
|
||||
@@ -263,6 +263,7 @@ static HAL_Status RKX12x_HAL_CRU_ClkSetFreq(struct hwclk *hw, uint32_t clockName
|
||||
uint32_t pll;
|
||||
uint8_t overMax;
|
||||
HAL_Status ret = HAL_OK;
|
||||
int i;
|
||||
|
||||
switch (clockName) {
|
||||
case RKX120_CPS_PLL_TXPLL:
|
||||
@@ -309,12 +310,21 @@ static HAL_Status RKX12x_HAL_CRU_ClkSetFreq(struct hwclk *hw, uint32_t clockName
|
||||
|
||||
/* PLL change closest new rate <= 1200M if need */
|
||||
if (!pRate) {
|
||||
pRate = (_MHZ(1200) / rate) * rate;
|
||||
}
|
||||
|
||||
ret = RKX12x_HAL_CRU_ClkSetFreq(hw, pll, pRate);
|
||||
if (ret != HAL_OK) {
|
||||
return ret;
|
||||
if (!rate || rate > _MHZ(1200))
|
||||
return HAL_ERROR;
|
||||
for (i = _MHZ(1200) / rate; i > _MHZ(24) / rate; i--) {
|
||||
pRate = i * rate;
|
||||
ret = RKX12x_HAL_CRU_ClkSetFreq(hw, pll, pRate);
|
||||
if (ret == HAL_OK)
|
||||
break;
|
||||
}
|
||||
if (ret != HAL_OK)
|
||||
return ret;
|
||||
} else {
|
||||
ret = RKX12x_HAL_CRU_ClkSetFreq(hw, pll, pRate);
|
||||
if (ret != HAL_OK) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* if success, continue to set divider */
|
||||
|
||||
@@ -92,6 +92,15 @@ static const struct spinand_info xincun_spinand_table[] = {
|
||||
&update_cache_variants),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&xcsp2aapk_ooblayout, xcsp2aapk_ecc_get_status)),
|
||||
SPINAND_INFO("XCSP1AAPK",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x01),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&xcsp2aapk_ooblayout, xcsp2aapk_ecc_get_status)),
|
||||
};
|
||||
|
||||
static const struct spinand_manufacturer_ops xincun_spinand_manuf_ops = {
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/wakelock.h>
|
||||
|
||||
#define RK630_PHY_ID 0x00441400
|
||||
@@ -71,6 +72,39 @@
|
||||
#define T22_TX_LEVEL_100M 0x2d
|
||||
#define T22_TX_LEVEL_10M 0x32
|
||||
|
||||
/* Long network cable parameters */
|
||||
#define RX_DETECT_SCHEDULE_TIME 500 /* ms */
|
||||
#define RX_DETECT_INIT_WAIT_TIME 2000 /* ms */
|
||||
|
||||
#define RX_DETECT_MAX_COUNT (5000 / RX_DETECT_SCHEDULE_TIME)
|
||||
#define ALL_RX_DETECT_MAX_COUNT (2 * RX_DETECT_MAX_COUNT)
|
||||
|
||||
#define LINKED_MAX_COUNT (10000 / RX_DETECT_SCHEDULE_TIME)
|
||||
#define ALL_LINKED_MAX_COUNT (2 * LINKED_MAX_COUNT)
|
||||
|
||||
#define RX_PACKET_RECEIVED_COUNTS 3 /* packets */
|
||||
#define RX_PACKET_RECEIVED_LOST 15 /* percent */
|
||||
|
||||
#define RX_SIGNAL_DETECT_TEMP 85000
|
||||
|
||||
struct rk630_phy_switched {
|
||||
/* record state */
|
||||
bool config;
|
||||
bool config_mode_10M;
|
||||
bool finished;
|
||||
|
||||
/* detected process */
|
||||
unsigned int detected_count;
|
||||
bool config_rx_signal;
|
||||
int old_link;
|
||||
|
||||
/* linked process */
|
||||
unsigned int linked_count;
|
||||
int rx_pkt_cnt;
|
||||
int rx_crc_err_cnt;
|
||||
int lost_percent;
|
||||
};
|
||||
|
||||
struct rk630_phy_priv {
|
||||
struct phy_device *phydev;
|
||||
bool ieee;
|
||||
@@ -78,6 +112,13 @@ struct rk630_phy_priv {
|
||||
struct wake_lock wol_wake_lock;
|
||||
int tx_level_100M;
|
||||
int tx_level_10M;
|
||||
|
||||
struct rk630_phy_switched switched;
|
||||
/* mutex protect variables between notify thread and delayed work */
|
||||
struct mutex lock;
|
||||
struct delayed_work service_task;
|
||||
struct thermal_zone_device *tz;
|
||||
bool disable_switch;
|
||||
};
|
||||
|
||||
static void rk630_phy_t22_get_tx_level_from_efuse(struct phy_device *phydev)
|
||||
@@ -192,6 +233,17 @@ static void rk630_phy_set_uaps(struct phy_device *phydev, bool enable)
|
||||
phy_write(phydev, REG_PAGE_SEL, 0x0000);
|
||||
}
|
||||
|
||||
static bool rk630_phy_rx_signal_detected(struct phy_device *phydev)
|
||||
{
|
||||
u32 value;
|
||||
|
||||
/* Switch to page 0 */
|
||||
phy_write(phydev, REG_PAGE_SEL, 0x0000);
|
||||
value = phy_read(phydev, 25);
|
||||
|
||||
return (value & BIT(15)) ? false : true;
|
||||
}
|
||||
|
||||
static void rk630_phy_s40_config_init(struct phy_device *phydev)
|
||||
{
|
||||
phy_write(phydev, 0, phy_read(phydev, 0) & ~BIT(13));
|
||||
@@ -229,8 +281,8 @@ static void rk630_phy_t22_config_init(struct phy_device *phydev)
|
||||
phy_write(phydev, REG_PAGE_SEL, 0x0100);
|
||||
/* Enable offset clock */
|
||||
phy_write(phydev, 0x10, 0xfbfe);
|
||||
/* Disable APS */
|
||||
phy_write(phydev, REG_PAGE1_APS_CTRL, 0x4824);
|
||||
/* Disable APS & Rx detected time 2s, default is 4s */
|
||||
phy_write(phydev, REG_PAGE1_APS_CTRL, 0x4822);
|
||||
/* Switch to page 2 */
|
||||
phy_write(phydev, REG_PAGE_SEL, 0x0200);
|
||||
/* PHYAFE TRX optimization */
|
||||
@@ -242,7 +294,15 @@ static void rk630_phy_t22_config_init(struct phy_device *phydev)
|
||||
/* PHYAFE Gain optimization */
|
||||
phy_write(phydev, REG_PAGE6_GAIN_ANONTROL, 0x0400);
|
||||
/* PHYAFE EQ optimization */
|
||||
phy_write(phydev, REG_PAGE6_AFE_TX_CTRL, 0x1088);
|
||||
|
||||
if (priv->disable_switch) {
|
||||
/* Rx detected default threshold 160 mv */
|
||||
phy_write(phydev, REG_PAGE6_AFE_TX_CTRL, 0x1088);
|
||||
} else {
|
||||
/* Rx detected threshold 260 mv */
|
||||
phy_write(phydev, REG_PAGE6_AFE_TX_CTRL, 0x10c8);
|
||||
priv->switched.config_rx_signal = true;
|
||||
}
|
||||
|
||||
if (priv->tx_level_100M <= 0 || priv->tx_level_10M <= 0)
|
||||
rk630_phy_t22_get_tx_level_from_efuse(phydev);
|
||||
@@ -305,23 +365,305 @@ static int rk630_phy_config_init(struct phy_device *phydev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk630_link_change_notify(struct phy_device *phydev)
|
||||
/* config0(default) and config1(0x555e) switched for 100/10M speed */
|
||||
static bool rk630_phy_switch_config(struct phy_device *phydev, bool config)
|
||||
{
|
||||
struct rk630_phy_priv *priv = phydev->priv;
|
||||
|
||||
if (priv->switched.config != config) {
|
||||
int val;
|
||||
|
||||
val = config ? 0x555e : 0x5540;
|
||||
phy_write(priv->phydev, REG_PAGE_SEL, 0x0600);
|
||||
phy_write(priv->phydev, REG_PAGE6_ADC_ANONTROL, val);
|
||||
phy_write(priv->phydev, REG_PAGE_SEL, 0x0000);
|
||||
priv->switched.config = config;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 10M speed configuration */
|
||||
static void rk630_phy_10m_switch_config(struct phy_device *phydev, bool config)
|
||||
{
|
||||
struct rk630_phy_priv *priv = phydev->priv;
|
||||
unsigned int val;
|
||||
|
||||
if (phydev->state == PHY_RUNNING || phydev->state == PHY_NOLINK) {
|
||||
/* Switch to page 6 */
|
||||
phy_write(phydev, REG_PAGE_SEL, 0x0600);
|
||||
if (config == priv->switched.config_mode_10M)
|
||||
return;
|
||||
|
||||
phy_write(phydev, REG_PAGE_SEL, 0x0600);
|
||||
val = phy_read(phydev, REG_PAGE6_AFE_TX_CTRL);
|
||||
val &= ~GENMASK(14, 13);
|
||||
if (config && !priv->switched.config_mode_10M)
|
||||
val |= BIT(13);
|
||||
|
||||
priv->switched.config_mode_10M = config;
|
||||
phy_write(phydev, REG_PAGE6_AFE_TX_CTRL, val);
|
||||
phy_write(priv->phydev, REG_PAGE_SEL, 0x0000);
|
||||
}
|
||||
|
||||
static void rk630_phy_switch_rx_signal_config(struct phy_device *phydev,
|
||||
bool config)
|
||||
{
|
||||
struct rk630_phy_priv *priv = phydev->priv;
|
||||
|
||||
if (priv->switched.config_rx_signal != config) {
|
||||
int val;
|
||||
|
||||
phy_write(priv->phydev, REG_PAGE_SEL, 0x0600);
|
||||
val = phy_read(phydev, REG_PAGE6_AFE_TX_CTRL);
|
||||
val &= ~GENMASK(14, 13);
|
||||
if (phydev->speed == SPEED_10 && phydev->link)
|
||||
val |= BIT(13);
|
||||
val &= ~GENMASK(7, 6);
|
||||
if (config)
|
||||
val |= GENMASK(7, 6);
|
||||
else
|
||||
val |= BIT(7);
|
||||
phy_write(phydev, REG_PAGE6_AFE_TX_CTRL, val);
|
||||
/* Switch to page 0 */
|
||||
phy_write(phydev, REG_PAGE_SEL, 0x0000);
|
||||
phy_write(priv->phydev, REG_PAGE_SEL, 0x0000);
|
||||
|
||||
priv->switched.config_rx_signal = config;
|
||||
}
|
||||
}
|
||||
|
||||
static void rk630_phy_packet_statistics(struct phy_device *phydev,
|
||||
int *total_cnt, int *crc_err_cnt)
|
||||
{
|
||||
struct rk630_phy_priv *priv = phydev->priv;
|
||||
|
||||
phy_write(priv->phydev, REG_PAGE_SEL, 0x0900);
|
||||
*total_cnt = phy_read(priv->phydev, 0x1b) << 16;
|
||||
*total_cnt |= phy_read(priv->phydev, 0x1c);
|
||||
*crc_err_cnt = phy_read(priv->phydev, 0x1d) << 16;
|
||||
*crc_err_cnt |= phy_read(priv->phydev, 0x1e);
|
||||
phy_write(phydev, REG_PAGE_SEL, 0x0000);
|
||||
}
|
||||
|
||||
static bool rk630_phy_switch_config_by_packets(struct phy_device *phydev)
|
||||
{
|
||||
struct rk630_phy_priv *priv = phydev->priv;
|
||||
int rx_pkt_cnt, rx_crc_err_cnt;
|
||||
int total_cnt, total_crc_err_cnt;
|
||||
int lost_percent;
|
||||
|
||||
rk630_phy_packet_statistics(phydev, &total_cnt, &total_crc_err_cnt);
|
||||
|
||||
rx_pkt_cnt = total_cnt - priv->switched.rx_pkt_cnt;
|
||||
rx_crc_err_cnt = total_crc_err_cnt - priv->switched.rx_crc_err_cnt;
|
||||
|
||||
priv->switched.rx_pkt_cnt = total_cnt;
|
||||
priv->switched.rx_crc_err_cnt = total_crc_err_cnt;
|
||||
|
||||
/* less than the minimal received packets during some time */
|
||||
if (rx_pkt_cnt < RX_PACKET_RECEIVED_COUNTS)
|
||||
return true;
|
||||
|
||||
/* Percents packets lost is not good during some time */
|
||||
lost_percent = (rx_crc_err_cnt * 100 / rx_pkt_cnt) > RX_PACKET_RECEIVED_LOST;
|
||||
|
||||
/* Just compare with config0's packet lost, update config if it is better
|
||||
* than config0.
|
||||
*/
|
||||
if (((rx_crc_err_cnt * 100 / rx_pkt_cnt) > RX_PACKET_RECEIVED_LOST) &&
|
||||
lost_percent > priv->switched.lost_percent) {
|
||||
/* Only save config0 lost percent */
|
||||
if (!priv->switched.config)
|
||||
priv->switched.lost_percent = lost_percent;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Only save config0 lost percent */
|
||||
if (!priv->switched.config)
|
||||
priv->switched.lost_percent = lost_percent;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void rk630_phy_service_task(struct work_struct *work)
|
||||
{
|
||||
struct rk630_phy_priv *priv = container_of(work, struct rk630_phy_priv,
|
||||
service_task.work);
|
||||
unsigned int delay_time;
|
||||
int ret, temp;
|
||||
|
||||
mutex_lock(&priv->lock);
|
||||
if (priv->disable_switch) {
|
||||
mutex_unlock(&priv->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!priv->phydev->link) {
|
||||
bool signal_detected;
|
||||
|
||||
signal_detected = rk630_phy_rx_signal_detected(priv->phydev);
|
||||
|
||||
/* Read signal */
|
||||
if (!signal_detected) {
|
||||
/* Slow schedule work for 2 * SCHEDULE_TIME, if no signal */
|
||||
priv->switched.detected_count = 0;
|
||||
priv->switched.lost_percent = 0;
|
||||
priv->switched.finished = false;
|
||||
priv->switched.linked_count = 0;
|
||||
delay_time = 2 * RX_DETECT_SCHEDULE_TIME;
|
||||
/* Goto default config if no rj45 signal plugin */
|
||||
rk630_phy_switch_config(priv->phydev, false);
|
||||
|
||||
/* Also go to 10M default config */
|
||||
rk630_phy_10m_switch_config(priv->phydev, false);
|
||||
} else {
|
||||
priv->switched.detected_count++;
|
||||
/* Fast schedule work for 1 * SCHEDULE_TIME, if signal
|
||||
* detected.
|
||||
*/
|
||||
delay_time = RX_DETECT_SCHEDULE_TIME;
|
||||
if (priv->switched.detected_count == RX_DETECT_MAX_COUNT &&
|
||||
!priv->switched.finished) {
|
||||
/* After it, there is no link, Might be a long cable,
|
||||
* config1 switched to get better performance during
|
||||
* some time.
|
||||
*/
|
||||
rk630_phy_switch_config(priv->phydev, true);
|
||||
} else if (priv->switched.detected_count == ALL_RX_DETECT_MAX_COUNT &&
|
||||
!priv->switched.finished) {
|
||||
/* After another detect, we lost the last chance,
|
||||
* go back to default config0.
|
||||
*/
|
||||
rk630_phy_switch_config(priv->phydev, false);
|
||||
priv->switched.finished = true;
|
||||
} else if (priv->switched.detected_count > ALL_RX_DETECT_MAX_COUNT ||
|
||||
priv->switched.finished) {
|
||||
/* Slow schedule work for 2 * SCHEDULE_TIME, if
|
||||
* detected finish.
|
||||
*/
|
||||
delay_time = 2 * RX_DETECT_SCHEDULE_TIME;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Detect the packet count and crc error count statistics */
|
||||
priv->switched.linked_count++;
|
||||
/* Fast schedule work for 1 * SCHEDULE_TIME, if linkup detected */
|
||||
delay_time = RX_DETECT_SCHEDULE_TIME;
|
||||
if (priv->switched.linked_count == LINKED_MAX_COUNT &&
|
||||
!priv->switched.finished) {
|
||||
if (rk630_phy_switch_config_by_packets(priv->phydev)) {
|
||||
/* Config1 switched to get better performance */
|
||||
rk630_phy_switch_config(priv->phydev, true);
|
||||
|
||||
/* Also go to 10M default config */
|
||||
if (priv->switched.config && priv->phydev->speed == SPEED_10)
|
||||
rk630_phy_10m_switch_config(priv->phydev, true);
|
||||
}
|
||||
} else if (priv->switched.linked_count == ALL_LINKED_MAX_COUNT &&
|
||||
!priv->switched.finished) {
|
||||
/* If config switched, we lost the last chance, return to
|
||||
* default config0.
|
||||
*/
|
||||
if (rk630_phy_switch_config_by_packets(priv->phydev)) {
|
||||
rk630_phy_switch_config(priv->phydev, false);
|
||||
rk630_phy_10m_switch_config(priv->phydev, false);
|
||||
}
|
||||
priv->switched.finished = true;
|
||||
} else if (priv->switched.linked_count > ALL_LINKED_MAX_COUNT ||
|
||||
priv->switched.finished) {
|
||||
/* Slow schedule work for 2 * SCHEDULE_TIME, if linkup
|
||||
* detected finish.
|
||||
*/
|
||||
delay_time = 2 * RX_DETECT_SCHEDULE_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->tz) {
|
||||
ret = thermal_zone_get_temp(priv->tz, &temp);
|
||||
if (ret || temp == THERMAL_TEMP_INVALID)
|
||||
phydev_err(priv->phydev,
|
||||
"failed to read out thermal zone (%d)\n", ret);
|
||||
else
|
||||
rk630_phy_switch_rx_signal_config(priv->phydev,
|
||||
(temp > RX_SIGNAL_DETECT_TEMP) ? false : true);
|
||||
}
|
||||
|
||||
schedule_delayed_work(&priv->service_task, msecs_to_jiffies(delay_time));
|
||||
mutex_unlock(&priv->lock);
|
||||
}
|
||||
|
||||
static void rk630_phy_link_change_notify(struct phy_device *phydev)
|
||||
{
|
||||
struct rk630_phy_priv *priv = phydev->priv;
|
||||
|
||||
if (phydev->mdio.addr == PHY_ADDR_T22) {
|
||||
mutex_lock(&priv->lock);
|
||||
if (priv->disable_switch) {
|
||||
mutex_unlock(&priv->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->switched.old_link && !phydev->link) {
|
||||
priv->switched.old_link = 0;
|
||||
priv->switched.linked_count = 0;
|
||||
schedule_delayed_work(&priv->service_task,
|
||||
msecs_to_jiffies(RX_DETECT_SCHEDULE_TIME));
|
||||
} else if (!priv->switched.old_link && phydev->link) {
|
||||
/* If linked, keep current config, but if the linked is
|
||||
* 10M speed, and config1 has been enabled, also switched
|
||||
* the 10M config.
|
||||
*/
|
||||
if (priv->switched.config && phydev->speed == SPEED_10)
|
||||
rk630_phy_10m_switch_config(phydev, true);
|
||||
|
||||
priv->switched.old_link = 1;
|
||||
priv->switched.detected_count = 0;
|
||||
/* Record base packet statistics to compare later, if linked */
|
||||
if (!priv->switched.linked_count)
|
||||
rk630_phy_packet_statistics(priv->phydev,
|
||||
&priv->switched.rx_pkt_cnt,
|
||||
&priv->switched.rx_crc_err_cnt);
|
||||
schedule_delayed_work(&priv->service_task,
|
||||
msecs_to_jiffies(RX_DETECT_SCHEDULE_TIME));
|
||||
}
|
||||
mutex_unlock(&priv->lock);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t rk630_phy_disable_switch_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct phy_device *phydev = to_phy_device(dev);
|
||||
struct rk630_phy_priv *priv = phydev->priv;
|
||||
int ret;
|
||||
bool disabled;
|
||||
|
||||
ret = kstrtobool(buf, &disabled);
|
||||
if (ret)
|
||||
return count;
|
||||
|
||||
mutex_lock(&priv->lock);
|
||||
if (disabled) {
|
||||
cancel_delayed_work_sync(&priv->service_task);
|
||||
|
||||
/* Save to default config */
|
||||
rk630_phy_10m_switch_config(priv->phydev, false);
|
||||
rk630_phy_switch_rx_signal_config(priv->phydev, false);
|
||||
rk630_phy_switch_config(priv->phydev, false);
|
||||
|
||||
memset(&priv->switched, 0, sizeof(struct rk630_phy_switched));
|
||||
} else {
|
||||
priv->switched.old_link = phydev->link;
|
||||
/* Rx detected threshold 260 mv */
|
||||
rk630_phy_switch_rx_signal_config(priv->phydev, true);
|
||||
|
||||
schedule_delayed_work(&priv->service_task,
|
||||
msecs_to_jiffies(RX_DETECT_INIT_WAIT_TIME));
|
||||
}
|
||||
priv->disable_switch = disabled;
|
||||
dev_info(dev, "rk630 phy disable switch to %s\n", disabled ? "true" : "false");
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR_WO(rk630_phy_disable_switch);
|
||||
|
||||
static irqreturn_t rk630_wol_irq_thread(int irq, void *dev_id)
|
||||
{
|
||||
struct rk630_phy_priv *priv = (struct rk630_phy_priv *)dev_id;
|
||||
@@ -334,6 +676,7 @@ static irqreturn_t rk630_wol_irq_thread(int irq, void *dev_id)
|
||||
static int rk630_phy_probe(struct phy_device *phydev)
|
||||
{
|
||||
struct rk630_phy_priv *priv;
|
||||
const char *tz_name;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
|
||||
@@ -362,6 +705,23 @@ static int rk630_phy_probe(struct phy_device *phydev)
|
||||
enable_irq_wake(priv->wol_irq);
|
||||
}
|
||||
|
||||
mutex_init(&priv->lock);
|
||||
INIT_DELAYED_WORK(&priv->service_task, rk630_phy_service_task);
|
||||
|
||||
priv->disable_switch = of_property_read_bool(phydev->mdio.dev.of_node,
|
||||
"rk630,phy-disable-switch");
|
||||
of_property_read_string(phydev->mdio.dev.of_node, "rockchip,thermal-zone",
|
||||
&tz_name);
|
||||
priv->tz = thermal_zone_get_zone_by_name(tz_name);
|
||||
if (IS_ERR(priv->tz)) {
|
||||
pr_warn("Error getting thermal zone, not yet ready?\n");
|
||||
priv->tz = NULL;
|
||||
}
|
||||
|
||||
ret = device_create_file(&phydev->mdio.dev, &dev_attr_rk630_phy_disable_switch);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->phydev = phydev;
|
||||
|
||||
return 0;
|
||||
@@ -384,6 +744,10 @@ static int rk630_phy_suspend(struct phy_device *phydev)
|
||||
phy_write(phydev, REG_INTERRUPT_MASK, BIT(14));
|
||||
enable_irq(priv->wol_irq);
|
||||
}
|
||||
|
||||
if (!priv->disable_switch)
|
||||
cancel_delayed_work_sync(&priv->service_task);
|
||||
|
||||
return genphy_suspend(phydev);
|
||||
}
|
||||
|
||||
@@ -397,6 +761,10 @@ static int rk630_phy_resume(struct phy_device *phydev)
|
||||
disable_irq(priv->wol_irq);
|
||||
}
|
||||
|
||||
if (!priv->disable_switch)
|
||||
schedule_delayed_work(&priv->service_task,
|
||||
msecs_to_jiffies(RX_DETECT_INIT_WAIT_TIME));
|
||||
|
||||
return genphy_resume(phydev);
|
||||
}
|
||||
|
||||
@@ -407,7 +775,7 @@ static struct phy_driver rk630_phy_driver[] = {
|
||||
.name = "RK630 PHY",
|
||||
.features = PHY_BASIC_FEATURES,
|
||||
.flags = 0,
|
||||
.link_change_notify = rk630_link_change_notify,
|
||||
.link_change_notify = rk630_phy_link_change_notify,
|
||||
.probe = rk630_phy_probe,
|
||||
.remove = rk630_phy_remove,
|
||||
.soft_reset = genphy_soft_reset,
|
||||
|
||||
@@ -92,6 +92,7 @@ struct optee_supp {
|
||||
struct list_head reqs;
|
||||
struct idr idr;
|
||||
struct completion reqs_c;
|
||||
bool shutdown;
|
||||
};
|
||||
|
||||
struct optee_smc {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/arm-smccc.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
@@ -1352,6 +1353,11 @@ static void optee_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct optee *optee = platform_get_drvdata(pdev);
|
||||
|
||||
/* Tell requesting thread to interrupt an RPC */
|
||||
smp_store_mb(optee->supp.shutdown, true);
|
||||
/* Wait requesting thread to release resources */
|
||||
mdelay(200);
|
||||
|
||||
if (!optee->rpc_param_count)
|
||||
optee_disable_shm_cache(optee);
|
||||
}
|
||||
|
||||
@@ -82,7 +82,6 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
|
||||
struct optee_supp_req *req;
|
||||
bool interruptable;
|
||||
u32 ret;
|
||||
unsigned long timeleft;
|
||||
int id;
|
||||
struct optee_supp_req *get_req;
|
||||
|
||||
@@ -117,14 +116,12 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
|
||||
* exclusive access again.
|
||||
*/
|
||||
while (wait_for_completion_interruptible(&req->c)) {
|
||||
pr_err("Warning, Interrupting an RPC to supplicant!\n");
|
||||
timeleft = wait_for_completion_timeout(&req->c, msecs_to_jiffies(2000));
|
||||
if (timeleft) {
|
||||
/* get completion, it means tee-supplicant is alive. */
|
||||
break;
|
||||
} else {
|
||||
/* timeout, it means tee-supplicant is dead, interrupting an RPC. */
|
||||
if (supp->shutdown) {
|
||||
/* Reboot happen, tee-supplicant is dead, interrupt an RPC */
|
||||
interruptable = true;
|
||||
} else {
|
||||
/* Deep sleep, tee-supplicant is freeze, wait tee-supplicant */
|
||||
continue;
|
||||
}
|
||||
|
||||
mutex_lock(&supp->mutex);
|
||||
|
||||
@@ -467,87 +467,6 @@ free_task:
|
||||
#define AV1_PP_TILE_SIZE GENMASK_ULL(10, 9)
|
||||
#define AV1_PP_TILE_16X16 BIT(10)
|
||||
|
||||
#define AV1_PP_OUT_LUMA_ADR_INDEX 326
|
||||
#define AV1_PP_OUT_CHROMA_ADR_INDEX 328
|
||||
|
||||
#define AV1_L2_CACHE_SHAPER_CTRL 0x20
|
||||
#define AV1_L2_CACHE_SHAPER_EN BIT(0)
|
||||
#define AV1_L2_CACHE_INT_MASK 0x30
|
||||
#define AV1_L2_CACHE_PP0_Y_CONFIG0 0x84
|
||||
#define AV1_L2_CACHE_PP0_Y_CONFIG2 0x8c
|
||||
#define AV1_L2_CACHE_PP0_Y_CONFIG3 0x90
|
||||
#define AV1_L2_CACHE_PP0_U_CONFIG0 0x98
|
||||
#define AV1_L2_CACHE_PP0_U_CONFIG2 0xa0
|
||||
#define AV1_L2_CACHE_PP0_U_CONFIG3 0xa4
|
||||
|
||||
#define AV1_L2_CACHE_RD_ONLY_CTRL 0x204
|
||||
#define AV1_L2_CACHE_RD_ONLY_CONFIG 0x208
|
||||
|
||||
static int av1dec_set_l2_cache(struct av1dec_dev *dec, struct av1dec_task *task)
|
||||
{
|
||||
int val;
|
||||
u32 *regs = (u32 *)task->reg_class[0].data;
|
||||
u32 width = (regs[4] >> 19) * 8;
|
||||
u32 height = ((regs[4] >> 6) & 0x1fff) * 8;
|
||||
u32 pixel_width = (((regs[322]) >> 27) & 0x1F) == 1 ? 8 : 16;
|
||||
u32 pre_fetch_height = 136;
|
||||
u32 max_h;
|
||||
u32 line_cnt;
|
||||
u32 line_size;
|
||||
u32 line_stride;
|
||||
|
||||
/* channel 4, PPU0_Y Configuration */
|
||||
/* afbc sharper can't use open cache.
|
||||
* afbc out must be tile 16x16.
|
||||
*/
|
||||
if ((regs[AV1_PP_CONFIG_INDEX] & AV1_PP_TILE_SIZE) != AV1_PP_TILE_16X16) {
|
||||
line_size = MPP_ALIGN(MPP_ALIGN(width * pixel_width, 8) / 8, 16);
|
||||
line_stride = MPP_ALIGN(MPP_ALIGN(width * pixel_width, 8) / 8, 16) >> 4;
|
||||
line_cnt = height;
|
||||
max_h = pre_fetch_height;
|
||||
|
||||
writel_relaxed(regs[AV1_PP_OUT_LUMA_ADR_INDEX] + 0x1,
|
||||
dec->reg_base[AV1DEC_CLASS_CACHE] + AV1_L2_CACHE_PP0_Y_CONFIG0);
|
||||
val = line_size | (line_stride << 16);
|
||||
writel_relaxed(val, dec->reg_base[AV1DEC_CLASS_CACHE] + AV1_L2_CACHE_PP0_Y_CONFIG2);
|
||||
|
||||
val = line_cnt | (max_h << 16);
|
||||
writel_relaxed(val, dec->reg_base[AV1DEC_CLASS_CACHE] + AV1_L2_CACHE_PP0_Y_CONFIG3);
|
||||
|
||||
/* channel 5, PPU0_U Configuration */
|
||||
line_size = MPP_ALIGN(MPP_ALIGN(width * pixel_width, 8) / 8, 16);
|
||||
line_stride = MPP_ALIGN(MPP_ALIGN(width * pixel_width, 8) / 8, 16) >> 4;
|
||||
line_cnt = height >> 1;
|
||||
max_h = pre_fetch_height >> 1;
|
||||
|
||||
writel_relaxed(regs[AV1_PP_OUT_CHROMA_ADR_INDEX] + 0x1,
|
||||
dec->reg_base[AV1DEC_CLASS_CACHE] + AV1_L2_CACHE_PP0_U_CONFIG0);
|
||||
val = line_size | (line_stride << 16);
|
||||
writel_relaxed(val, dec->reg_base[AV1DEC_CLASS_CACHE] + AV1_L2_CACHE_PP0_U_CONFIG2);
|
||||
|
||||
val = line_cnt | (max_h << 16);
|
||||
writel_relaxed(val, dec->reg_base[AV1DEC_CLASS_CACHE] + AV1_L2_CACHE_PP0_U_CONFIG3);
|
||||
/* mask cache irq */
|
||||
writel_relaxed(0xf, dec->reg_base[AV1DEC_CLASS_CACHE] + AV1_L2_CACHE_INT_MASK);
|
||||
|
||||
/* shaper enable */
|
||||
writel_relaxed(AV1_L2_CACHE_SHAPER_EN,
|
||||
dec->reg_base[AV1DEC_CLASS_CACHE] + AV1_L2_CACHE_SHAPER_CTRL);
|
||||
|
||||
/* not enable cache en when multi tiles */
|
||||
if (!(regs[10] & BIT(1)))
|
||||
/* cache all en */
|
||||
writel_relaxed(0x00000001, dec->reg_base[AV1DEC_CLASS_CACHE] +
|
||||
AV1_L2_CACHE_RD_ONLY_CONFIG);
|
||||
/* reorder_e and cache_e */
|
||||
writel_relaxed(0x00000081, dec->reg_base[AV1DEC_CLASS_CACHE] +
|
||||
AV1_L2_CACHE_RD_ONLY_CTRL);
|
||||
/* wmb */
|
||||
wmb();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#define REG_CONTROL 0x20
|
||||
#define REG_INTRENBL 0x34
|
||||
#define REG_ACKNOWLEDGE 0x38
|
||||
@@ -656,7 +575,6 @@ static int av1dec_run(struct mpp_dev *mpp, struct mpp_task *mpp_task)
|
||||
|
||||
mpp_debug_enter();
|
||||
mpp_iommu_flush_tlb(mpp->iommu_info);
|
||||
av1dec_set_l2_cache(dec, task);
|
||||
av1dec_set_afbc(dec, task);
|
||||
|
||||
for (i = 0; i < task->w_req_cnt; i++) {
|
||||
|
||||
Reference in New Issue
Block a user