Merge commit '95a90239c174bfb41a9d21b265a8b6df0eafc089'

* commit '95a90239c174bfb41a9d21b265a8b6df0eafc089':
  misc: rk628: combtxphy: enabling ssc is required for frac_div
  UPSTREAM: mtd: Clean refcounting with MTD_PARTITIONED_MASTER
  UPSTREAM: mtd: call external _get and _put in right order
  UPSTREAM: mtd: fix use-after-free in mtd release
  UPSTREAM: mtd: use refcount to prevent corruption
  misc: rk628: bt1120: modify bt1120 decoder dclk delay
  drm/bridge: analogix_dp: modify the log related to the check of hpd status
  ARM: dts: rockchip: rk3506g-iotest: add wave clk_pwm_rc mode for pwm test
  pwm: rockchip-test: set the default configurations for clk_src and mem_clk_src
  spi: rockchip_slave: Remove redundant dma_map behavior
  pwm: rockchip: use existing enum definitions for width_mode and updata_mode settings
  pwm: rockchip: add support to select clk_src and mem_clk_src for wave generator mode
  regulator: rk801: Fix ramp_delay value error
  arm64: dts: rockchip: rk3576: remove dma for can
  arm64: dts: rockchip: rk3588-vehicle-evb: image reverse move xvclk to sensor
  arm64: dts: rockchip: rk3576-evb1: image reverse move xvclk to sensor node
  video: rockchip: vehicle: move xvclk ctrl to generic sensor

Change-Id: Ife5af50977c16e3f3020d5d0e016c5242bcfb826
This commit is contained in:
Tao Huang
2025-01-20 18:45:48 +08:00
22 changed files with 279 additions and 258 deletions

View File

@@ -40,32 +40,52 @@
status = "okay";
pinctrl-names = "active";
pinctrl-0 = <&rm_io8_pwm0_ch0>;
#ifdef WAVE_CLK_PWM_RC_TEST
clocks = <&cru CLK_RC_PWM0>, <&cru PCLK_PWM0>, <&cru CLK_OSC_PWM0>;
clock-names = "pwm", "pclk", "osc";
#else
assigned-clocks = <&cru CLK_PWM0>;
assigned-clock-rates = <100000000>;
#endif
};
&pwm0_4ch_1 {
status = "okay";
pinctrl-names = "active";
pinctrl-0 = <&rm_io9_pwm0_ch1>;
#ifdef WAVE_CLK_PWM_RC_TEST
clocks = <&cru CLK_RC_PWM0>, <&cru PCLK_PWM0>, <&cru CLK_OSC_PWM0>;
clock-names = "pwm", "pclk", "osc";
#else
assigned-clocks = <&cru CLK_PWM0>;
assigned-clock-rates = <100000000>;
#endif
};
&pwm0_4ch_2 {
status = "okay";
pinctrl-names = "active";
pinctrl-0 = <&rm_io10_pwm0_ch2>;
#ifdef WAVE_CLK_PWM_RC_TEST
clocks = <&cru CLK_RC_PWM0>, <&cru PCLK_PWM0>, <&cru CLK_OSC_PWM0>;
clock-names = "pwm", "pclk", "osc";
#else
assigned-clocks = <&cru CLK_PWM0>;
assigned-clock-rates = <100000000>;
#endif
};
&pwm0_4ch_3 {
status = "okay";
pinctrl-names = "active";
pinctrl-0 = <&rm_io11_pwm0_ch3>;
#ifdef WAVE_CLK_PWM_RC_TEST
clocks = <&cru CLK_RC_PWM0>, <&cru PCLK_PWM0>, <&cru CLK_OSC_PWM0>;
clock-names = "pwm", "pclk", "osc";
#else
assigned-clocks = <&cru CLK_PWM0>;
assigned-clock-rates = <100000000>;
#endif
};
&pwm1_8ch_0 {

View File

@@ -94,12 +94,10 @@
csi2_dcphy0 {
status = "disabled";
clocks = <&cru CLK_MIPI_CAMERAOUT_M0>,
<&cru PCLK_MIPI_DCPHY>,
clocks = <&cru PCLK_MIPI_DCPHY>,
<&cru PCLK_CSI_HOST_0>,
<&cru ICLK_CSIHOST0>;
clock-names = "xvclk",
"pclk",
clock-names = "pclk",
"pclk_csi2host",
"iclk_csi2host";
resets = <&cru SRST_P_CSI_HOST_0>;
@@ -111,11 +109,9 @@
};
csi2_dphy0 {
status = "disabled";
clocks = <&cru CLK_MIPI_CAMERAOUT_M1>,
<&cru PCLK_CSIDPHY>,
clocks = <&cru PCLK_CSIDPHY>,
<&cru PCLK_CSI_HOST_1>;
clock-names = "xvclk",
"pclk",
clock-names = "pclk",
"pclk_csi2host";
resets = <&cru SRST_P_CSIPHY>,
<&cru SRST_P_CSI_HOST_1>;
@@ -129,14 +125,12 @@
};
csi2_dphy3 {
status = "okay";
clocks = <&cru CLK_MIPI_CAMERAOUT_M2>,
<&cru PCLK_CSIDPHY1>,
<&cru PCLK_CSI_HOST_3>;
clock-names = "xvclk",
"pclk",
clocks = <&cru PCLK_CSIDPHY1>,
<&cru PCLK_CSI_HOST_3>;
clock-names = "pclk",
"pclk_csi2host";
resets = <&cru SRST_P_CSIDPHY1>,
<&cru SRST_P_CSI_HOST_3>;
<&cru SRST_P_CSI_HOST_3>;
reset-names = "srst_p_csiphy",
"srst_csihost_p";
csihost-idx = <3>;
@@ -153,6 +147,8 @@
nvp6324 {
status = "okay";
clocks = <&cru CLK_MIPI_CAMERAOUT_M1>;
clock-names = "xvclk";
//dphy3
powerdown-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
pwdn_active = <1>;

View File

@@ -5447,8 +5447,6 @@
clock-names = "baudclk", "apb_pclk";
resets = <&cru SRST_CAN0>, <&cru SRST_H_CAN0>;
reset-names = "can", "can-apb";
dmas = <&dmac0 20>;
dma-names = "rx";
status = "disabled";
};
@@ -5460,8 +5458,6 @@
clock-names = "baudclk", "apb_pclk";
resets = <&cru SRST_CAN1>, <&cru SRST_H_CAN1>;
reset-names = "can", "can-apb";
dmas = <&dmac1 21>;
dma-names = "rx";
status = "disabled";
};

View File

@@ -77,12 +77,10 @@
csi2_dcphy0 {
status = "disabled";
clocks = <&cru CLK_MIPI_CAMARAOUT_M1>,
<&cru PCLK_MIPI_DCPHY0>,
clocks = <&cru PCLK_MIPI_DCPHY0>,
<&cru PCLK_CSI_HOST_0>,
<&cru ICLK_CSIHOST0>;
clock-names = "xvclk",
"pclk",
clock-names = "pclk",
"pclk_csi2host",
"iclk_csi2host";
resets = <&cru SRST_P_CSI_HOST_0>,
@@ -96,12 +94,10 @@
};
csi2_dcphy1 {
status = "disabled";
clocks = <&cru CLK_MIPI_CAMARAOUT_M2>,
<&cru PCLK_MIPI_DCPHY1>,
clocks = <&cru PCLK_MIPI_DCPHY1>,
<&cru PCLK_CSI_HOST_1>,
<&cru ICLK_CSIHOST1>;
clock-names = "xvclk",
"pclk",
clock-names = "pclk",
"pclk_csi2host",
"iclk_csi2host";
resets = <&cru SRST_P_CSI_HOST_1>,
@@ -115,11 +111,9 @@
};
csi2_dphy0 {
status = "okay";
clocks = <&cru CLK_MIPI_CAMARAOUT_M2>,
<&cru PCLK_CSIPHY0>,
clocks = <&cru PCLK_CSIPHY0>,
<&cru PCLK_CSI_HOST_2>;
clock-names = "xvclk",
"pclk",
clock-names = "pclk",
"pclk_csi2host";
resets = <&cru SRST_CSIPHY0>,
<&cru SRST_P_CSIPHY0>,
@@ -137,11 +131,9 @@
/* only rk3588 */
csi2_dphy3 {
status = "disabled";
clocks = <&cru CLK_MIPI_CAMARAOUT_M4>,
<&cru PCLK_CSIPHY1>,
clocks = <&cru PCLK_CSIPHY1>,
<&cru PCLK_CSI_HOST_4>;
clock-names = "xvclk",
"pclk",
clock-names = "pclk",
"pclk_csi2host";
resets = <&cru SRST_CSIPHY1>,
<&cru SRST_P_CSIPHY1>,
@@ -158,8 +150,6 @@
};
rkcif_dvp {
status = "disabled";
clocks = <&cru CLK_CIFOUT_OUT>;
clock-names = "xvclk";
};
};
@@ -170,7 +160,8 @@
nvp6188 {
is_front = <0>;
status = "okay";
clocks = <&cru CLK_MIPI_CAMARAOUT_M2>;
clock-names = "xvclk";
/*dphy0*/
powerdown-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>;
pwdn_active = <1>;

View File

@@ -178,7 +178,7 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
analogix_dp_force_hpd(dp);
if (analogix_dp_get_plug_in_status(dp) != 0) {
dev_err(dp->dev, "failed to get hpd plug in status\n");
dev_dbg(dp->dev, "hpd status is detected as disconnected\n");
return -EINVAL;
}

View File

@@ -27,6 +27,12 @@ static void rk628_combtxphy_dsi_power_on(struct rk628 *rk628)
rk628_i2c_update_bits(rk628, COMBTXPHY_CON0,
SW_MODULEB_EN_MASK, SW_MODULEB_EN);
rk628_i2c_update_bits(rk628, COMBTXPHY_CON0, SW_PD_PLL, SW_PD_PLL);
if (combtxphy->frac_div)
rk628_i2c_update_bits(rk628, COMBTXPHY_CON8, SW_SSC_DEPTH_MASK | SW_SSC_EN_MASK,
SW_SSC_DEPTH(0) | SW_SSC_EN(1));
rk628_i2c_write(rk628, COMBTXPHY_CON5,
SW_REF_DIV(combtxphy->ref_div - 1) |
SW_PLL_FB_DIV(combtxphy->fb_div) |
@@ -201,7 +207,7 @@ void rk628_combtxphy_set_gvi_division_mode(struct rk628 *rk628, bool division)
void rk628_combtxphy_set_mode(struct rk628 *rk628, enum phy_mode mode)
{
struct rk628_combtxphy *combtxphy = &rk628->combtxphy;
unsigned int fvco, fpfd, frac_rate, fin = 24;
unsigned int fvco, fpfd, fin = 24;
switch (mode) {
case PHY_MODE_VIDEO_MIPI:
@@ -210,7 +216,14 @@ void rk628_combtxphy_set_mode(struct rk628 *rk628, enum phy_mode mode)
unsigned int fhsc = bus_width >> 8;
unsigned int flags = bus_width & 0xff;
fhsc = fin * (fhsc / fin);
combtxphy->flags = flags;
/*
* the VCO can work from 1.5GHz to 3GHz.
* fhsc: 80 ~ 374, fvco: 640 ~ 2992
* fhsc: 375 ~ 749, fvco: 1500 ~ 2996
* fhsc: 750 ~ 1500, fvco: 1500 ~ 3000
*/
if (fhsc < 80 || fhsc > 1500)
return;
else if (fhsc < 375)
@@ -220,22 +233,26 @@ void rk628_combtxphy_set_mode(struct rk628 *rk628, enum phy_mode mode)
else
combtxphy->rate_div = 1;
combtxphy->flags = flags;
fvco = fhsc * 2 * combtxphy->rate_div;
combtxphy->ref_div = 1;
combtxphy->fb_div = fvco / 8 / fin;
frac_rate = fvco - (fin * 8 * combtxphy->fb_div);
if (frac_rate) {
frac_rate <<= 10;
frac_rate /= fin * 8;
combtxphy->frac_div = frac_rate;
} else {
combtxphy->frac_div = 0;
}
fvco = fin * (1024 * combtxphy->fb_div + combtxphy->frac_div);
fvco *= 8;
/*
* the reference clock at PFD(FPFD = ref_clk / ref_div) about
* 25MHz is recommende, FPFD must range from 16MHz to 35MHz,
* here to find the best ref_div.
*/
combtxphy->ref_div = 1;
/*
* fvco = fin * (fb_div + frac_div / 1024) * 8 / ref_div
*/
combtxphy->fb_div = fvco * combtxphy->ref_div / 8 / fin;
combtxphy->frac_div = 1024 * fvco * combtxphy->ref_div / 8 / fin;
combtxphy->frac_div -= 1024 * combtxphy->fb_div;
/*
* get the actually frequency
*/
fvco = fin * (1024 * combtxphy->fb_div + combtxphy->frac_div) * 8;
fvco = DIV_ROUND_UP(fvco, 1024 * combtxphy->ref_div);
fhsc = fvco / 2 / combtxphy->rate_div;
combtxphy->bus_width = fhsc;

View File

@@ -58,6 +58,10 @@
#define TX_COM_VOLT_ADJ(x) UPDATE(x, 2, 0)
#define COMBTXPHY_CON8 REG(0x0020)
#define SW_SSC_DEPTH_MASK GENMASK(7, 4)
#define SW_SSC_DEPTH(x) UPDATE(x, 7, 4)
#define SW_SSC_EN_MASK BIT(0)
#define SW_SSC_EN(x) UPDATE(x, 0, 0)
#define COMBTXPHY_CON9 REG(0x0024)
#define SW_DSI_FSET_EN_MASK BIT(29)
#define SW_DSI_FSET_EN BIT(29)

View File

@@ -294,7 +294,7 @@ static void rk628_bt1120_decoder_enable(struct rk628 *rk628)
} else {
if (rk628->version == RK628F_VERSION) {
rk628_i2c_write(rk628, GRF_BT1120_DCLK_DELAY_CON0,
0x08000000);
0x1);
rk628_i2c_write(rk628, GRF_BT1120_DCLK_DELAY_CON1, 0);
}
}

View File

@@ -92,10 +92,39 @@ static void mtd_release(struct device *dev)
struct mtd_info *mtd = dev_get_drvdata(dev);
dev_t index = MTD_DEVT(mtd->index);
idr_remove(&mtd_idr, mtd->index);
of_node_put(mtd_get_of_node(mtd));
if (mtd_is_partition(mtd))
release_mtd_partition(mtd);
/* remove /dev/mtdXro node */
device_destroy(&mtd_class, index + 1);
}
static void mtd_device_release(struct kref *kref)
{
struct mtd_info *mtd = container_of(kref, struct mtd_info, refcnt);
bool is_partition = mtd_is_partition(mtd);
debugfs_remove_recursive(mtd->dbg.dfs_dir);
/* Try to remove the NVMEM provider */
nvmem_unregister(mtd->nvmem);
device_unregister(&mtd->dev);
/*
* Clear dev so mtd can be safely re-registered later if desired.
* Should not be done for partition,
* as it was already destroyed in device_unregister().
*/
if (!is_partition)
memset(&mtd->dev, 0, sizeof(mtd->dev));
module_put(THIS_MODULE);
}
#define MTD_DEVICE_ATTR_RO(name) \
static DEVICE_ATTR(name, 0444, mtd_##name##_show, NULL)
@@ -674,7 +703,7 @@ int add_mtd_device(struct mtd_info *mtd)
}
mtd->index = i;
mtd->usecount = 0;
kref_init(&mtd->refcnt);
/* default value if not set by driver */
if (mtd->bitflip_threshold == 0)
@@ -776,7 +805,6 @@ int del_mtd_device(struct mtd_info *mtd)
{
int ret;
struct mtd_notifier *not;
struct device_node *mtd_of_node;
mutex_lock(&mtd_table_mutex);
@@ -790,28 +818,8 @@ int del_mtd_device(struct mtd_info *mtd)
list_for_each_entry(not, &mtd_notifiers, list)
not->remove(mtd);
if (mtd->usecount) {
printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n",
mtd->index, mtd->name, mtd->usecount);
ret = -EBUSY;
} else {
mtd_of_node = mtd_get_of_node(mtd);
debugfs_remove_recursive(mtd->dbg.dfs_dir);
/* Try to remove the NVMEM provider */
nvmem_unregister(mtd->nvmem);
device_unregister(&mtd->dev);
/* Clear dev so mtd can be safely re-registered later if desired */
memset(&mtd->dev, 0, sizeof(mtd->dev));
idr_remove(&mtd_idr, mtd->index);
of_node_put(mtd_of_node);
module_put(THIS_MODULE);
ret = 0;
}
kref_put(&mtd->refcnt, mtd_device_release);
ret = 0;
out_error:
mutex_unlock(&mtd_table_mutex);
@@ -1207,25 +1215,27 @@ int __get_mtd_device(struct mtd_info *mtd)
struct mtd_info *master = mtd_get_master(mtd);
int err;
if (!try_module_get(master->owner))
return -ENODEV;
if (master->_get_device) {
err = master->_get_device(mtd);
if (err) {
module_put(master->owner);
if (err)
return err;
}
}
master->usecount++;
if (!try_module_get(master->owner)) {
if (master->_put_device)
master->_put_device(master);
return -ENODEV;
}
while (mtd->parent) {
mtd->usecount++;
while (mtd) {
if (mtd != master)
kref_get(&mtd->refcnt);
mtd = mtd->parent;
}
if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
kref_get(&master->refcnt);
return 0;
}
EXPORT_SYMBOL_GPL(__get_mtd_device);
@@ -1309,18 +1319,23 @@ void __put_mtd_device(struct mtd_info *mtd)
{
struct mtd_info *master = mtd_get_master(mtd);
while (mtd->parent) {
--mtd->usecount;
BUG_ON(mtd->usecount < 0);
mtd = mtd->parent;
while (mtd) {
/* kref_put() can relese mtd, so keep a reference mtd->parent */
struct mtd_info *parent = mtd->parent;
if (mtd != master)
kref_put(&mtd->refcnt, mtd_device_release);
mtd = parent;
}
master->usecount--;
if (master->_put_device)
master->_put_device(master);
if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
kref_put(&master->refcnt, mtd_device_release);
module_put(master->owner);
/* must be the last as master can be freed in the _put_device */
if (master->_put_device)
master->_put_device(master);
}
EXPORT_SYMBOL_GPL(__put_mtd_device);

View File

@@ -12,6 +12,7 @@ int __must_check add_mtd_device(struct mtd_info *mtd);
int del_mtd_device(struct mtd_info *mtd);
int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
int del_mtd_partitions(struct mtd_info *);
void release_mtd_partition(struct mtd_info *mtd);
struct mtd_partitions;

View File

@@ -32,6 +32,12 @@ static inline void free_partition(struct mtd_info *mtd)
kfree(mtd);
}
void release_mtd_partition(struct mtd_info *mtd)
{
WARN_ON(!list_empty(&mtd->part.node));
free_partition(mtd);
}
static struct mtd_info *allocate_partition(struct mtd_info *parent,
const struct mtd_partition *part,
int partno, uint64_t cur_offset)
@@ -309,13 +315,11 @@ static int __mtd_del_partition(struct mtd_info *mtd)
sysfs_remove_files(&mtd->dev.kobj, mtd_partition_attrs);
list_del_init(&mtd->part.node);
err = del_mtd_device(mtd);
if (err)
return err;
list_del(&mtd->part.node);
free_partition(mtd);
return 0;
}
@@ -334,6 +338,7 @@ static int __del_mtd_partitions(struct mtd_info *mtd)
__del_mtd_partitions(child);
pr_info("Deleting %s MTD partition\n", child->name);
list_del_init(&child->part.node);
ret = del_mtd_device(child);
if (ret < 0) {
pr_err("Error when deleting partition \"%s\" (%d)\n",
@@ -341,9 +346,6 @@ static int __del_mtd_partitions(struct mtd_info *mtd)
err = ret;
continue;
}
list_del(&child->part.node);
free_partition(child);
}
return err;

View File

@@ -633,17 +633,17 @@ static ssize_t pwm_rockchip_test_write(struct file *file, const char __user *buf
duty_table.offset = (channel_id % 3) * PWM_TABLE_MAX;
duty_table.len = PWM_TABLE_MAX;
wave_config.rpt = PWM_WAVE_RPT;
/* select the 400k clk src */
wave_config.clk_rate = 400000;
wave_config.duty_table = &duty_table;
wave_config.period_table = NULL;
wave_config.clk_src = PWM_SELECT_CLK_PWM;
wave_config.mem_clk_src = PWM_SELECT_CLK_PWM_OSC;
wave_config.width_mode = PWM_WIDTH_MODE;
wave_config.update_mode = PWM_WAVE_INCREASING_THEN_DECREASING;
wave_config.enable = enable;
wave_config.duty_en = true;
wave_config.period_en = false;
wave_config.width_mode = PWM_WIDTH_MODE;
wave_config.update_mode = PWM_WAVE_INCREASING_THEN_DECREASING;
wave_config.clk_rate = 400000;
wave_config.rpt = PWM_WAVE_RPT;
wave_config.duty_max = (channel_id % 3 + 1) * PWM_TABLE_MAX - 1;
wave_config.duty_min = (channel_id % 3) * PWM_TABLE_MAX;
wave_config.period_max = 0;

View File

@@ -1599,7 +1599,8 @@ static int rockchip_pwm_set_wave_v4(struct pwm_chip *chip, struct pwm_device *pw
ctrl = WAVE_DUTY_EN(config->duty_en) |
WAVE_PERIOD_EN(config->period_en) |
WAVE_WIDTH_MODE(config->width_mode) |
WAVE_UPDATE_MODE(config->update_mode);
WAVE_UPDATE_MODE(config->update_mode) |
WAVE_MEM_CLK_SEL(config->mem_clk_src);
max_val = config->duty_max * factor << WAVE_DUTY_MAX_SHIFT |
config->period_max * factor << WAVE_PERIOD_MAX_SHIFT;
min_val = config->duty_min * factor << WAVE_DUTY_MIN_SHIFT |
@@ -1613,7 +1614,7 @@ static int rockchip_pwm_set_wave_v4(struct pwm_chip *chip, struct pwm_device *pw
ctrl = WAVE_DUTY_EN(false) | WAVE_PERIOD_EN(false);
}
writel_relaxed(CLK_SCALE(pc->scaler), pc->base + CLK_CTRL);
writel_relaxed(CLK_SCALE(pc->scaler) | CLK_SRC_SEL(config->clk_src), pc->base + CLK_CTRL);
writel_relaxed(ctrl, pc->base + WAVE_CTRL);
writel_relaxed(max_val, pc->base + WAVE_MAX);
writel_relaxed(min_val, pc->base + WAVE_MIN);

View File

@@ -341,7 +341,7 @@ static const struct regulator_desc rk801_reg[] = {
.enable_mask = ENABLE_MASK(RK801_ID_DCDC1),
.enable_val = ENABLE_VAL(RK801_ID_DCDC1),
.disable_val = DISABLE_VAL(RK801_ID_DCDC1),
.ramp_delay = 1,
.ramp_delay = 1000,
.of_map_mode = rk801_regulator_of_map_mode,
.enable_time = 400,
.owner = THIS_MODULE,
@@ -362,7 +362,7 @@ static const struct regulator_desc rk801_reg[] = {
.enable_mask = ENABLE_MASK(RK801_ID_DCDC2),
.enable_val = ENABLE_VAL(RK801_ID_DCDC2),
.disable_val = DISABLE_VAL(RK801_ID_DCDC2),
.ramp_delay = 1,
.ramp_delay = 1000,
.of_map_mode = rk801_regulator_of_map_mode,
.enable_time = 400,
.owner = THIS_MODULE,
@@ -399,7 +399,7 @@ static const struct regulator_desc rk801_reg[] = {
.enable_mask = ENABLE_MASK(RK801_ID_DCDC4),
.enable_val = ENABLE_VAL(RK801_ID_DCDC4),
.disable_val = DISABLE_VAL(RK801_ID_DCDC4),
.ramp_delay = 1,
.ramp_delay = 1000,
.of_map_mode = rk801_regulator_of_map_mode,
.enable_time = 400,
.owner = THIS_MODULE,

View File

@@ -471,6 +471,20 @@ static int rockchip_spi_slave_prepare_dma(struct rockchip_spi *rs,
return 1;
}
static bool rockchip_spi_slave_can_dma(struct spi_controller *ctlr,
struct spi_device *spi,
struct spi_transfer *xfer)
{
struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
unsigned int bytes_per_word = xfer->bits_per_word <= 8 ? 1 : 2;
/* if the numbor of spi words to transfer is less than the fifo
* length we can just fill the fifo and wait for a single irq,
* so don't bother setting up dma
*/
return xfer->len / bytes_per_word >= rs->fifo_len;
}
static int rockchip_spi_slave_config(struct rockchip_spi *rs,
struct spi_device *spi, struct spi_transfer *xfer)
{
@@ -673,7 +687,7 @@ static int rockchip_spi_slave_do_one_msg(struct spi_controller *ctlr, struct spi
rs->n_bytes = xfer->bits_per_word <= 8 ? 1 : 2;
rs->xfer = xfer;
use_dma = ctlr->can_dma(ctlr, spi, xfer);
use_dma = rockchip_spi_slave_can_dma(ctlr, spi, xfer);
if (use_dma)
rs->xfer_mode = ROCKCHIP_SPI_DMA;
else
@@ -724,20 +738,6 @@ out:
return 0;
}
static bool rockchip_spi_slave_can_dma(struct spi_controller *ctlr,
struct spi_device *spi,
struct spi_transfer *xfer)
{
struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
unsigned int bytes_per_word = xfer->bits_per_word <= 8 ? 1 : 2;
/* if the numbor of spi words to transfer is less than the fifo
* length we can just fill the fifo and wait for a single irq,
* so don't bother setting up dma
*/
return xfer->len / bytes_per_word >= rs->fifo_len;
}
static int rockchip_spi_slave_setup(struct spi_device *spi)
{
struct rockchip_spi *rs = spi_controller_get_devdata(spi->controller);
@@ -885,7 +885,6 @@ static int rockchip_spi_slave_probe(struct platform_device *pdev)
}
rs->dma_addr_tx = mem->start + ROCKCHIP_SPI_TXDR;
rs->dma_addr_rx = mem->start + ROCKCHIP_SPI_RXDR;
ctlr->can_dma = rockchip_spi_slave_can_dma;
init_completion(&rs->xfer_done);
switch (rs->version) {

View File

@@ -64,6 +64,7 @@ struct vehicle_ad_dev {
u8 detect_status;
u8 last_detect_status;
int drop_frames;
struct clk *xvclk;
};
int vehicle_generic_sensor_write(struct vehicle_ad_dev *ad, char reg, char *pval);
@@ -74,7 +75,7 @@ int vehicle_parse_sensor(struct vehicle_ad_dev *ad);
void vehicle_ad_channel_set(struct vehicle_ad_dev *ad, int channel);
int vehicle_ad_init(struct vehicle_ad_dev *ad);
int vehicle_ad_deinit(void);
int vehicle_ad_deinit(struct vehicle_ad_dev *ad);
int vehicle_ad_stream(struct vehicle_ad_dev *ad, int val);
struct vehicle_cfg *vehicle_ad_get_vehicle_cfg(void);
void vehicle_ad_check_cif_error(struct vehicle_ad_dev *ad, int last_line);

View File

@@ -3313,33 +3313,7 @@ err:
return ret;
}
/* sensor mclk set */
static void rkcif_s_mclk(struct vehicle_cif *cif, int on, int clk_rate)
{
int err = 0;
struct device *dev = cif->dev;
struct rk_cif_clk *clk = &cif->clk;
//return ;
if (on && !clk->on) {
if (!IS_ERR(clk->xvclk)) {
err = clk_set_rate(clk->xvclk, clk_rate);
if (err < 0)
dev_err(dev, "Failed to set xvclk rate (24MHz)\n");
}
if (!IS_ERR(clk->xvclk)) {
err = clk_prepare_enable(clk->xvclk);
if (err < 0)
dev_err(dev, "Failed to enable xvclk\n");
}
} else {
if (!IS_ERR(clk->xvclk))
clk_disable_unprepare(clk->xvclk);
}
usleep_range(2000, 5000);
}
static int rk_cif_mclk_ctrl(struct vehicle_cif *cif, int on, int clk_rate)
static int rk_cif_mclk_ctrl(struct vehicle_cif *cif, int on)
{
int err = 0;
@@ -5130,36 +5104,14 @@ int vehicle_cif_reverse_close(void)
return 0;
}
static void vehicle_cif_dphy_get_node(struct vehicle_cif *cif)
{
struct device_node *node = NULL;
struct device_node *cp = NULL;
struct device *dev = cif->dev;
const char *status = NULL;
node = of_parse_phandle(dev->of_node, "rockchip,cif-phy", 0);
if (!node) {
VEHICLE_DGERR("get cif-phy dts failed\n");
return;
}
for_each_child_of_node(node, cp) {
of_property_read_string(cp, "status", &status);
if (status && !strcmp(status, "disabled"))
continue;
else
cif->phy_node = cp;
VEHICLE_INFO("status: %s %s\n", cp->name, status);
}
}
static int cif_parse_dt(struct vehicle_cif *cif)
{
struct device *dev = cif->dev;
struct device_node *node;
struct device_node *phy_node = cif->phy_node;
struct device_node *phy_node;
struct device_node *cif_node;
struct device_node *cis2_node;
const char *status = NULL;
if (of_property_read_u32(dev->of_node, "cif,drop-frames",
&cif->drop_frames)) {
@@ -5178,127 +5130,112 @@ static int cif_parse_dt(struct vehicle_cif *cif)
node = of_parse_phandle(dev->of_node, "rockchip,cru", 0);
cif->cru_base = of_iomap(node, 0);
of_node_put(node);
node = of_parse_phandle(dev->of_node, "rockchip,grf", 0);
cif->grf_base = of_iomap(node, 0);
of_node_put(node);
cif->regmap_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
if (IS_ERR(cif->regmap_grf))
VEHICLE_DGERR("unable to get rockchip,grf\n");
cif->irq = irq_of_parse_and_map(cif_node, 0);
of_node_put(cif_node);
if (cif->irq < 0) {
VEHICLE_DGERR("%s: request cif irq failed\n", __func__);
iounmap(cif->base);
iounmap(cif->cru_base);
iounmap(cif->grf_base);
return -ENODEV;
goto unmap_cif;
}
if (of_property_read_u32(phy_node, "csihost-idx", &cif->csi_host_idx)) {
node = of_parse_phandle(dev->of_node, "rockchip,cif-phy", 0);
if (!node) {
VEHICLE_DGERR("get cif-phy dts failed\n");
goto unmap_cif;
}
for_each_child_of_node(node, phy_node) {
of_property_read_string(phy_node, "status", &status);
if (status && !strcmp(status, "disabled"))
continue;
else
cif->phy_node = phy_node;
VEHICLE_INFO("status: %s %s\n", cif->phy_node->name, status);
}
of_node_put(node);
if (of_property_read_u32(cif->phy_node, "csihost-idx", &cif->csi_host_idx)) {
VEHICLE_INFO("Get %s csihost-idx failed! sensor link to dvp!!\n",
phy_node->name);
cif->phy_node->name);
cif->inf_id = RKCIF_DVP;
} else {
cif->inf_id = RKCIF_MIPI_LVDS;
VEHICLE_INFO("sensor link to %s!!\n", phy_node->name);
VEHICLE_INFO("sensor link to %s!!\n", cif->phy_node->name);
}
if (cif->inf_id == RKCIF_MIPI_LVDS) {
if (cif->chip_id == CHIP_RK3588_VEHICLE_CIF &&
!(cif->csi_host_idx == RKCIF_MIPI0_CSI2 ||
cif->csi_host_idx == RKCIF_MIPI1_CSI2)) {
node = of_parse_phandle(phy_node, "rockchip,csi2-dphy", 0);
node = of_parse_phandle(cif->phy_node, "rockchip,csi2-dphy", 0);
cif->csi2_dphy_base = of_iomap(node, 0);
of_node_put(node);
cif->regmap_dphy_grf =
syscon_regmap_lookup_by_phandle(phy_node, "rockchip,dphy-grf");
syscon_regmap_lookup_by_phandle(cif->phy_node, "rockchip,dphy-grf");
if (IS_ERR(cif->regmap_dphy_grf))
VEHICLE_INFO("unable to get rockchip,dphy-grf\n");
} else if (cif->chip_id == CHIP_RK3576_VEHICLE_CIF &&
cif->csi_host_idx != RKCIF_MIPI0_CSI2) {
node = of_parse_phandle(phy_node, "rockchip,csi2-dphy", 0);
node = of_parse_phandle(cif->phy_node, "rockchip,csi2-dphy", 0);
cif->csi2_dphy_base = of_iomap(node, 0);
of_node_put(node);
cif->regmap_dphy_grf =
syscon_regmap_lookup_by_phandle(phy_node, "rockchip,dphy-grf");
syscon_regmap_lookup_by_phandle(cif->phy_node, "rockchip,dphy-grf");
if (IS_ERR(cif->regmap_dphy_grf))
VEHICLE_INFO("unable to get rockchip,dphy-grf\n");
cif->dphy_sys_grf =
syscon_regmap_lookup_by_phandle(phy_node, "rockchip,sys-grf");
syscon_regmap_lookup_by_phandle(cif->phy_node, "rockchip,sys-grf");
if (IS_ERR(cif->dphy_sys_grf))
VEHICLE_INFO("unable to get rockchip,sys-grf\n");
} else if (cif->chip_id != CHIP_RK3588_VEHICLE_CIF &&
cif->chip_id != CHIP_RK3576_VEHICLE_CIF) {
node = of_parse_phandle(phy_node, "rockchip,csi2-dphy", 0);
node = of_parse_phandle(cif->phy_node, "rockchip,csi2-dphy", 0);
cif->csi2_dphy_base = of_iomap(node, 0);
of_node_put(node);
}
cis2_node = of_parse_phandle(phy_node, "rockchip,csi2", 0);
cis2_node = of_parse_phandle(cif->phy_node, "rockchip,csi2", 0);
cif->csi2_base = of_iomap(cis2_node, 0);
cif->csi2_irq1 = irq_of_parse_and_map(cis2_node, 0);
if (cif->csi2_irq1 < 0) {
VEHICLE_DGERR("%s: request csi-intr1 failed\n", __func__);
iounmap(cif->base);
iounmap(cif->cru_base);
iounmap(cif->grf_base);
iounmap(cif->csi2_dphy_base);
iounmap(cif->csi2_base);
return -ENODEV;
of_node_put(cis2_node);
goto unmap_csi;
}
cif->csi2_irq2 = irq_of_parse_and_map(cis2_node, 1);
of_node_put(cis2_node);
if (cif->csi2_irq2 < 0) {
VEHICLE_DGERR("%s: request csi-intr2 failed\n", __func__);
iounmap(cif->base);
iounmap(cif->cru_base);
iounmap(cif->grf_base);
iounmap(cif->csi2_dphy_base);
iounmap(cif->csi2_base);
return -ENODEV;
goto unmap_csi;
}
}
VEHICLE_DG("%s, drop_frames = %d\n", __func__, cif->drop_frames);
return 0;
}
int vehicle_cif_init_mclk(struct vehicle_cif *cif)
{
struct device *dev = cif->dev;
struct rk_cif_clk *clk = &cif->clk;
unmap_csi:
iounmap(cif->csi2_dphy_base);
iounmap(cif->csi2_base);
unmap_cif:
iounmap(cif->base);
iounmap(cif->cru_base);
iounmap(cif->grf_base);
/* sensor MCLK:
* current use CLK_CIF_OUT
*/
vehicle_cif_dphy_get_node(cif);
clk->xvclk = of_clk_get_by_name(cif->phy_node, "xvclk");
if (IS_ERR(clk->xvclk)) {
dev_err(dev, "Failed to get sensor xvclk\n");
return -EINVAL;
}
rkcif_s_mclk(cif, 1, 24000000);
VEHICLE_INFO("%s(%d): set sensor MCLK rate 24MHZ OK!\n", __func__, __LINE__);
return 0;
}
static int vehicle_cif_deinit_mclk(struct vehicle_cif *cif)
{
struct rk_cif_clk *clk = &cif->clk;
/* release sensor MCLK:
* current use CLK_CIF_OUT
*/
if (!IS_ERR(clk->xvclk))
clk_disable_unprepare(clk->xvclk);
clk_put(clk->xvclk);
return 0;
return -ENODEV;
}
int vehicle_cif_init(struct vehicle_cif *cif)
@@ -5553,7 +5490,7 @@ int vehicle_cif_init(struct vehicle_cif *cif)
}
/* 2. set cif clk & sensor mclk */
rk_cif_mclk_ctrl(cif, 1, 24000000);
rk_cif_mclk_ctrl(cif, 1);
INIT_DELAYED_WORK(&cif->work, vehicle_cif_reset_work_func);
if (inf_id == RKCIF_MIPI_LVDS)
@@ -5665,15 +5602,12 @@ int vehicle_cif_deinit(struct vehicle_cif *cif)
// vehicle_cif_s_stream(cif, 0);
// vehicle_cif_do_stop_stream(cif);
/* set csi2-dphy csi cif clk & sensor mclk */
rk_cif_mclk_ctrl(cif, 0, 0);
/* set csi2-dphy csi cif clk */
rk_cif_mclk_ctrl(cif, 0);
if (inf_id == RKCIF_MIPI_LVDS)
if (cif->dphy_hw->on)
vehicle_csi2_clk_ctrl(cif, 0);
/* release sensor MCLK */
vehicle_cif_deinit_mclk(cif);
/* vicap rsts release */
for (i = 0; i < clk->rsts_num; i++)
reset_control_put(clk->cif_rst[i]);

View File

@@ -37,7 +37,6 @@ struct vehicle_rkcif_dummy_buffer {
struct rk_cif_clk {
/************clk************/
struct clk *clks[RKCIF_MAX_BUS_CLK];
struct clk *xvclk;
int clks_num;
/************reset************/
struct reset_control *cif_rst[RKCIF_MAX_RESET];

View File

@@ -12,6 +12,8 @@
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/of_gpio.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include "vehicle_ad.h"
#include "vehicle_ad_7181.h"
#include "vehicle_ad_tp2855.h"
@@ -328,6 +330,12 @@ int vehicle_parse_sensor(struct vehicle_ad_dev *ad)
ad->reset = of_get_named_gpio_flags(cp, "reset-gpios",
0, &flags);
ad->xvclk = of_clk_get_by_name(cp, "xvclk");
if (IS_ERR(ad->xvclk)) {
ad->xvclk = NULL;
VEHICLE_DGERR("Failed to get sensor xvclk, maybe unuse\n");
}
if (of_property_read_u32(cp, "i2c_add", &ad->i2c_add))
VEHICLE_DGERR("Get %s i2c_add failed!\n", cp->name);
@@ -382,6 +390,24 @@ int vehicle_parse_sensor(struct vehicle_ad_dev *ad)
return ret;
}
static void vehicle_ad_mclk_set(struct vehicle_ad_dev *ad, int on)
{
int err = 0;
int clk_rate = ad->mclk_rate * 1000000;
if (on) {
err = clk_set_rate(ad->xvclk, clk_rate);
if (err < 0)
VEHICLE_DGERR("Failed to set xvclk rate (%dMHz)\n", ad->mclk_rate);
clk_prepare_enable(ad->xvclk);
if (err < 0)
VEHICLE_DGERR("Failed to enable xvclk\n");
} else {
clk_disable_unprepare(ad->xvclk);
}
usleep_range(2000, 5000);
}
void vehicle_ad_channel_set(struct vehicle_ad_dev *ad, int channel)
{
if (sensor_cb && sensor_cb->sensor_set_channel)
@@ -394,6 +420,7 @@ int vehicle_ad_init(struct vehicle_ad_dev *ad)
//WARN_ON(1);
VEHICLE_DGERR("%s(%d) ad_name:%s!", __func__, __LINE__, ad->ad_name);
vehicle_ad_mclk_set(ad, 1);
if (sensor_cb && sensor_cb->sensor_init) {
ret = sensor_cb->sensor_init(ad);
if (ret < 0) {
@@ -416,7 +443,7 @@ end:
return ret;
}
int vehicle_ad_deinit(void)
int vehicle_ad_deinit(struct vehicle_ad_dev *ad)
{
int ret = 0;
@@ -425,6 +452,9 @@ int vehicle_ad_deinit(void)
else
ret = -EINVAL;
clk_disable_unprepare(ad->xvclk);
clk_put(ad->xvclk);
return ret;
}

View File

@@ -426,9 +426,8 @@ static int rk_vehicle_system_main(void *arg)
/* 1.ad */
VEHICLE_DG("%s: vehicle_ad_init start\r\n", __func__);
/* config mclk first */
ret = vehicle_cif_init_mclk(&v->cif);
ret |= vehicle_ad_init(&v->ad);
ret = vehicle_ad_init(&v->ad);
if (ret < 0) {
VEHICLE_DGERR("%s: ad init failed\r\n", __func__);
goto VEHICLE_AD_DEINIT;
@@ -464,7 +463,7 @@ VEHICLE_CIF_DEINIT:
vehicle_cif_deinit(&v->cif);
VEHICLE_AD_DEINIT:
vehicle_ad_deinit();
vehicle_ad_deinit(&v->ad);
VEHICLE_GPIO_DEINIT:
vehicle_gpio_deinit(&v->gpio_data);

View File

@@ -379,7 +379,7 @@ struct mtd_info {
struct module *owner;
struct device dev;
int usecount;
struct kref refcnt;
struct mtd_debug_info dbg;
struct nvmem_device *nvmem;
struct nvmem_device *otp_user_nvmem;

View File

@@ -8,6 +8,18 @@
#include <linux/pwm.h>
/**
* enum rockchip_pwm_clk_src_sel - select the clk src of pwm
* @PWM_SELECT_CLK_PWM: select clk_pwm as clk src
* @PWM_SELECT_CLK_PWM_OSC: select clk_pwm_osc as clk src
* @PWM_SELECT_CLK_PWM_RC: select clk_pwm_rc as clk src
*/
enum rockchip_pwm_clk_src_sel {
PWM_SELECT_CLK_PWM,
PWM_SELECT_CLK_PWM_OSC,
PWM_SELECT_CLK_PWM_RC,
};
/**
* enum rockchip_pwm_global_ctrl_cmd - commands for pwm global ctrl
* @PWM_GLOBAL_CTRL_JOIN: join the global control group
@@ -89,13 +101,15 @@ enum rockchip_pwm_wave_update_mode {
* struct rockchip_pwm_wave_config - wave generator config object
* @duty_table: the wave table config of duty
* @period_table: the wave table config of period
* @clk_src: the clk src selection in wave generator mode
* @mem_clk_src: the memory clk src selection in wave generator mode
* @width_mode: the width mode of wave table
* @update_mode: the update mode of wave generator
* @enable: enable or disable wave generator
* @duty_en: to update duty by duty table or not
* @period_en: to update period by period table or not
* @clk_rate: the dclk rate in wave generator mode
* @rpt: the number of repeated effective periods
* @width_mode: the width mode of wave table
* @update_mode: the update mode of wave generator
* @duty_max: the maximum address of duty table
* @duty_min: the minimum address of duty table
* @period_max: the maximum address of period table
@@ -109,13 +123,15 @@ enum rockchip_pwm_wave_update_mode {
struct rockchip_pwm_wave_config {
struct rockchip_pwm_wave_table *duty_table;
struct rockchip_pwm_wave_table *period_table;
enum rockchip_pwm_clk_src_sel clk_src;
enum rockchip_pwm_clk_src_sel mem_clk_src;
enum rockchip_pwm_wave_table_width_mode width_mode;
enum rockchip_pwm_wave_update_mode update_mode;
bool enable;
bool duty_en;
bool period_en;
unsigned long clk_rate;
u16 rpt;
u32 width_mode;
u32 update_mode;
u32 duty_max;
u32 duty_min;
u32 period_max;