diff --git a/arch/arm/boot/dts/rk3506g-iotest-pwm-test.dtsi b/arch/arm/boot/dts/rk3506g-iotest-pwm-test.dtsi index 0434275de148..18ec9d236b36 100644 --- a/arch/arm/boot/dts/rk3506g-iotest-pwm-test.dtsi +++ b/arch/arm/boot/dts/rk3506g-iotest-pwm-test.dtsi @@ -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 { diff --git a/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-image-reverse-vehicle.dtsi b/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-image-reverse-vehicle.dtsi index 06de135ed768..5c2caea977c9 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-image-reverse-vehicle.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10-image-reverse-vehicle.dtsi @@ -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>; diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi index e25899a39eff..172122edae4f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi @@ -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"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-image-reverse.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-image-reverse.dtsi index fa4255a273c8..eb226e926b30 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-image-reverse.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-image-reverse.dtsi @@ -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>; diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index ede08c45b199..6ac47ad2cc36 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -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; } diff --git a/drivers/misc/rk628/rk628_combtxphy.c b/drivers/misc/rk628/rk628_combtxphy.c index 2cc73482d16f..bd131db59afc 100644 --- a/drivers/misc/rk628/rk628_combtxphy.c +++ b/drivers/misc/rk628/rk628_combtxphy.c @@ -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; diff --git a/drivers/misc/rk628/rk628_combtxphy.h b/drivers/misc/rk628/rk628_combtxphy.h index efc91b9e010e..0174f5160d1c 100644 --- a/drivers/misc/rk628/rk628_combtxphy.h +++ b/drivers/misc/rk628/rk628_combtxphy.h @@ -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) diff --git a/drivers/misc/rk628/rk628_rgb.c b/drivers/misc/rk628/rk628_rgb.c index a8aed6f90e87..ee0de851307e 100644 --- a/drivers/misc/rk628/rk628_rgb.c +++ b/drivers/misc/rk628/rk628_rgb.c @@ -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); } } diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index ad527bdbd463..6f887492c1b9 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -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); diff --git a/drivers/mtd/mtdcore.h b/drivers/mtd/mtdcore.h index b5eefeabf310..b014861a06a6 100644 --- a/drivers/mtd/mtdcore.h +++ b/drivers/mtd/mtdcore.h @@ -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; diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 85f5ee6f06fc..73f9e371a04d 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -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; diff --git a/drivers/pwm/pwm-rockchip-test.c b/drivers/pwm/pwm-rockchip-test.c index 59294260298d..757013141fe5 100644 --- a/drivers/pwm/pwm-rockchip-test.c +++ b/drivers/pwm/pwm-rockchip-test.c @@ -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; diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c index 820d26e42cb1..26a7986b6157 100644 --- a/drivers/pwm/pwm-rockchip.c +++ b/drivers/pwm/pwm-rockchip.c @@ -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); diff --git a/drivers/regulator/rk801-regulator.c b/drivers/regulator/rk801-regulator.c index 349b2636ea3b..703db41c2bf3 100644 --- a/drivers/regulator/rk801-regulator.c +++ b/drivers/regulator/rk801-regulator.c @@ -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, diff --git a/drivers/spi/spi-rockchip-slave.c b/drivers/spi/spi-rockchip-slave.c index ed9e53bf13e6..58377839db0f 100644 --- a/drivers/spi/spi-rockchip-slave.c +++ b/drivers/spi/spi-rockchip-slave.c @@ -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) { diff --git a/drivers/video/rockchip/vehicle/vehicle_ad.h b/drivers/video/rockchip/vehicle/vehicle_ad.h index a83233b791e0..dd189459145d 100644 --- a/drivers/video/rockchip/vehicle/vehicle_ad.h +++ b/drivers/video/rockchip/vehicle/vehicle_ad.h @@ -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); diff --git a/drivers/video/rockchip/vehicle/vehicle_cif.c b/drivers/video/rockchip/vehicle/vehicle_cif.c index 082ed3b92881..85a441b1a6ba 100644 --- a/drivers/video/rockchip/vehicle/vehicle_cif.c +++ b/drivers/video/rockchip/vehicle/vehicle_cif.c @@ -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]); diff --git a/drivers/video/rockchip/vehicle/vehicle_cif.h b/drivers/video/rockchip/vehicle/vehicle_cif.h index 48481034c92a..372a30da80a2 100644 --- a/drivers/video/rockchip/vehicle/vehicle_cif.h +++ b/drivers/video/rockchip/vehicle/vehicle_cif.h @@ -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]; diff --git a/drivers/video/rockchip/vehicle/vehicle_generic_sensor.c b/drivers/video/rockchip/vehicle/vehicle_generic_sensor.c index 32102d7cdcb0..e277e61ddc92 100644 --- a/drivers/video/rockchip/vehicle/vehicle_generic_sensor.c +++ b/drivers/video/rockchip/vehicle/vehicle_generic_sensor.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include #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; } diff --git a/drivers/video/rockchip/vehicle/vehicle_main.c b/drivers/video/rockchip/vehicle/vehicle_main.c index dc9320034200..e306c40ab16e 100644 --- a/drivers/video/rockchip/vehicle/vehicle_main.c +++ b/drivers/video/rockchip/vehicle/vehicle_main.c @@ -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); diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 7c58c44662b8..914a9f974baa 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -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; diff --git a/include/linux/pwm-rockchip.h b/include/linux/pwm-rockchip.h index f3c550dcb2b0..75c4f43abde7 100644 --- a/include/linux/pwm-rockchip.h +++ b/include/linux/pwm-rockchip.h @@ -8,6 +8,18 @@ #include +/** + * 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;