diff --git a/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-cdp.dtsi index f71fbd38f70d..195fa2ac1a19 100644 --- a/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-cdp.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-cdp.dtsi @@ -294,7 +294,7 @@ eeprom-src = <&eeprom_rear>; cam_vio-supply = <&camera_vio_ldo>; cam_vana-supply = <&camera_vana_ldo>; - cam_vdig-supply = <&camera_rear_ldo>; + cam_vdig-supply = <&camera_ldo>; cam_clk-supply = <&titan_top_gdsc>; regulator-names = "cam_vio", "cam_vana", "cam_vdig", "cam_clk"; diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index cd481f49be3e..4bcfdc7d773c 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -3476,6 +3477,7 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer, len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, "%s%s%s%s%s\n", single_line, single_line, single_line, single_line, single_line); + spin_lock(&me->hlock); hlist_for_each_entry_safe(gmaps, n, &me->maps, hn) { len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, "%-20d|0x%-18llX|0x%-18X|0x%-20lX\n\n", @@ -3483,18 +3485,21 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer, (uint32_t)gmaps->size, gmaps->va); } + spin_unlock(&me->hlock); len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, "%-20s|%-20s|%-20s|%-20s\n", "len", "refs", "raddr", "flags"); len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, "%s%s%s%s%s\n", single_line, single_line, single_line, single_line, single_line); + spin_lock(&me->hlock); hlist_for_each_entry_safe(gmaps, n, &me->maps, hn) { len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, "0x%-18X|%-20d|%-20lu|%-20u\n", (uint32_t)gmaps->len, gmaps->refs, gmaps->raddr, gmaps->flags); } + spin_unlock(&me->hlock); } else { len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, "\n%s %13s %d\n", "cid", ":", fl->cid); @@ -3544,12 +3549,14 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer, "%s%s%s%s%s\n", single_line, single_line, single_line, single_line, single_line); + mutex_lock(&fl->map_mutex); hlist_for_each_entry_safe(map, n, &fl->maps, hn) { len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, "0x%-20lX|0x%-20llX|0x%-20zu\n\n", map->va, map->phys, map->size); } + mutex_unlock(&fl->map_mutex); len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, "%-20s|%-20s|%-20s|%-20s\n", "len", "refs", @@ -3558,23 +3565,27 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer, "%s%s%s%s%s\n", single_line, single_line, single_line, single_line, single_line); + mutex_lock(&fl->map_mutex); hlist_for_each_entry_safe(map, n, &fl->maps, hn) { len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, "%-20zu|%-20d|0x%-20lX|%-20d\n\n", map->len, map->refs, map->raddr, map->uncached); } + mutex_unlock(&fl->map_mutex); len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, "%-20s|%-20s\n", "secure", "attr"); len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, "%s%s%s%s%s\n", single_line, single_line, single_line, single_line, single_line); + mutex_lock(&fl->map_mutex); hlist_for_each_entry_safe(map, n, &fl->maps, hn) { len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, "%-20d|0x%-20lX\n\n", map->secure, map->attr); } + mutex_unlock(&fl->map_mutex); len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len, "%s %d\n\n", "KERNEL MEMORY ALLOCATION:", 1); diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index ba07d791c5b9..cb9f4e46607e 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -1739,7 +1739,16 @@ static int diag_send_dci_pkt_remote(unsigned char *data, int len, int tag, write_len += dci_header_size; *(int *)(buf + write_len) = tag; write_len += sizeof(int); - memcpy(buf + write_len, data, len); + if ((write_len + len) < DIAG_MDM_BUF_SIZE) { + memcpy(buf + write_len, data, len); + } else { + pr_err("diag: skip writing invalid length packet, token: %d, pkt_len: %d\n", + token, (write_len + len)); + spin_lock_irqsave(&driver->dci_mempool_lock, flags); + diagmem_free(driver, buf, dci_ops_tbl[token].mempool); + spin_unlock_irqrestore(&driver->dci_mempool_lock, flags); + return -EAGAIN; + } write_len += len; *(buf + write_len) = CONTROL_CHAR; /* End Terminator */ write_len += sizeof(uint8_t); diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 4e4043fca223..20a8a571a5ac 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -862,10 +862,10 @@ static int drm_atomic_plane_check(struct drm_plane *plane, int ret; /* either *both* CRTC and FB must be set, or neither */ - if (WARN_ON(state->crtc && !state->fb)) { + if (state->crtc && !state->fb) { DRM_DEBUG_ATOMIC("CRTC set but no FB\n"); return -EINVAL; - } else if (WARN_ON(state->fb && !state->crtc)) { + } else if (state->fb && !state->crtc) { DRM_DEBUG_ATOMIC("FB set but no CRTC\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 8164c6f6b9de..a1c7d7fa6f23 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -411,6 +411,30 @@ int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link) } EXPORT_SYMBOL(drm_dp_link_power_down); +int drm_dp_link_power_down_aux_up(struct drm_dp_aux *aux, + struct drm_dp_link *link) +{ + u8 value; + int err; + + if (link->revision < 0x11) + return 0; + + err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value); + if (err < 0) + return err; + + value &= ~DP_SET_POWER_MASK; + value |= DP_SET_POWER_D5; + + err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value); + if (err < 0) + return err; + + return 0; +} +EXPORT_SYMBOL(drm_dp_link_power_down_aux_up); + /** * drm_dp_link_configure() - configure a DisplayPort link * @aux: DisplayPort AUX channel diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c b/drivers/gpu/drm/msm/dp/dp_debug.c index 97de1b803f55..a3d2ebb550c6 100644 --- a/drivers/gpu/drm/msm/dp/dp_debug.c +++ b/drivers/gpu/drm/msm/dp/dp_debug.c @@ -25,6 +25,8 @@ #include "sde_connector.h" #include "dp_display.h" +#include + #define DEBUG_NAME "drm_dp" struct dp_debug_private { @@ -50,6 +52,13 @@ struct dp_debug_private { struct work_struct sim_work; struct dp_debug dp_debug; struct mutex lock; + struct dp_ctrl *ctrl; +}; + +enum dpms_mode_status { + DRM_DPMS_ON = 1, + DRM_DPMS_OFF = 2, + DRM_DPMS_SUSPEND = 5, }; static int dp_debug_get_edid_buf(struct dp_debug_private *debug) @@ -985,6 +994,77 @@ end: return len; } +static ssize_t dp_debug_write_dpms(struct file *file, + const char __user *user_buff, size_t count, loff_t *ppos) +{ + int dpms_mode; + struct dp_debug_private *debug = file->private_data; + char buf[SZ_8]; + size_t len = 0; + enum dpms_mode_status mode_status; + + len = min_t(size_t, count, SZ_8-1); + if (copy_from_user(buf, user_buff, len)) + goto end; + + buf[len] = '\0'; + + if (kstrtoint(buf, 8, &dpms_mode)) { + pr_err("offset kstrtoint error\n"); + return 0; + } + + if (!debug->aux || !debug->aux->drm_aux || !debug->panel) + return 0; + + pr_info("dpms_mode = %d", dpms_mode); + mode_status = dpms_mode; + switch (mode_status) { + case DRM_DPMS_ON: + drm_dp_link_power_up(debug->aux->drm_aux, + &debug->panel->link_info); + debug->ctrl->link_maintenance(debug->ctrl); + break; + case DRM_DPMS_OFF: + drm_dp_link_power_down(debug->aux->drm_aux, + &debug->panel->link_info); + break; + case DRM_DPMS_SUSPEND: + drm_dp_link_power_down_aux_up(debug->aux->drm_aux, + &debug->panel->link_info); + break; + default: + pr_err("Invalid values\n"); + } +end: + return count; +} + +static ssize_t dp_debug_read_dpms(struct file *file, + char __user *user_buff, size_t count, loff_t *ppos) +{ + u8 value; + int err, len; + char buf[SZ_8]; + struct dp_debug_private *debug = file->private_data; + + err = drm_dp_dpcd_readb(debug->aux->drm_aux, DP_SET_POWER, &value); + if (err < 0) + return err; + + if (*ppos) + return 0; + + len += snprintf(buf, SZ_8, "%d\n", value); + + len = min_t(size_t, count, len); + if (copy_to_user(user_buff, buf, len)) + return -EFAULT; + + *ppos += len; + return len; +} + static ssize_t dp_debug_write_dump(struct file *file, const char __user *user_buff, size_t count, loff_t *ppos) { @@ -1121,6 +1201,12 @@ static const struct file_operations dump_fops = { .read = dp_debug_read_dump, }; +static const struct file_operations dpms_mode_fops = { + .open = simple_open, + .write = dp_debug_write_dpms, + .read = dp_debug_read_dpms, +}; + static int dp_debug_init(struct dp_debug *dp_debug) { int rc = 0; @@ -1260,6 +1346,16 @@ static int dp_debug_init(struct dp_debug *dp_debug) goto error_remove_dir; } + file = debugfs_create_file("dpms_mode", 0644, dir, + debug, &dpms_mode_fops); + + if (IS_ERR_OR_NULL(file)) { + rc = PTR_ERR(file); + pr_err("[%s] debugfs dpms failed, rc=%d\n", + DEBUG_NAME, rc); + goto error_remove_dir; + } + return 0; error_remove_dir: @@ -1281,13 +1377,13 @@ static void dp_debug_sim_work(struct work_struct *work) struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, struct dp_usbpd *usbpd, struct dp_link *link, struct dp_aux *aux, struct drm_connector **connector, - struct dp_catalog *catalog) + struct dp_catalog *catalog, struct dp_ctrl *ctrl) { int rc = 0; struct dp_debug_private *debug; struct dp_debug *dp_debug; - if (!dev || !panel || !usbpd || !link || !catalog) { + if (!dev || !panel || !usbpd || !link || !catalog || !ctrl) { pr_err("invalid input\n"); rc = -EINVAL; goto error; @@ -1309,6 +1405,7 @@ struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, debug->dev = dev; debug->connector = connector; debug->catalog = catalog; + debug->ctrl = ctrl; dp_debug = &debug->dp_debug; dp_debug->vdisplay = 0; diff --git a/drivers/gpu/drm/msm/dp/dp_debug.h b/drivers/gpu/drm/msm/dp/dp_debug.h index 2643f70f219d..2f08a188822f 100644 --- a/drivers/gpu/drm/msm/dp/dp_debug.h +++ b/drivers/gpu/drm/msm/dp/dp_debug.h @@ -19,6 +19,7 @@ #include "dp_link.h" #include "dp_usbpd.h" #include "dp_aux.h" +#include "dp_ctrl.h" /** * struct dp_debug @@ -56,7 +57,7 @@ struct dp_debug { struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, struct dp_usbpd *usbpd, struct dp_link *link, struct dp_aux *aux, struct drm_connector **connector, - struct dp_catalog *catalog); + struct dp_catalog *catalog, struct dp_ctrl *ctrl); /** * dp_debug_put() * diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 331d6ade2454..e967eb6c9bc9 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -977,7 +977,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp) dp->debug = dp_debug_get(dev, dp->panel, dp->usbpd, dp->link, dp->aux, &dp->dp_display.connector, - dp->catalog); + dp->catalog, dp->ctrl); if (IS_ERR(dp->debug)) { rc = PTR_ERR(dp->debug); pr_err("failed to initialize debug, rc = %d\n", rc); @@ -1414,6 +1414,60 @@ static int dp_display_get_modes(struct dp_display *dp, return ret; } +int dp_display_set_power(struct drm_connector *connector, + int power_mode, void *disp) +{ + struct dp_display *dp = disp; + struct dp_display_private *dp_priv = + container_of(dp, struct dp_display_private, dp_display); + int rc = 0; + + if (!dp) { + pr_err("invalid display\n"); + return -EINVAL; + } + + if (!dp_priv) { + pr_err("invalid display private\n"); + return -EINVAL; + } + + if (!dp_priv->panel) { + pr_err("invalid link_info\n"); + return -EINVAL; + } + + if (!dp_priv->aux->drm_aux) { + pr_err("Invalid drm_aux"); + return -EINVAL; + } + + if (!dp_priv->link) { + pr_err("invalid dp_link\n"); + return -EINVAL; + } + + switch (power_mode) { + case SDE_MODE_DPMS_STANDBY: + dp_priv->link->power_mode = DRM_MODE_DPMS_STANDBY; + rc = dp_priv->link->psm_config(dp_priv->link, + &dp_priv->panel->link_info, true); + dp_priv->ctrl->push_idle(dp_priv->ctrl); + break; + case SDE_MODE_DPMS_SUSPEND: + dp_priv->link->power_mode = DRM_MODE_DPMS_SUSPEND; + rc = dp_priv->link->psm_config(dp_priv->link, + &dp_priv->panel->link_info, true); + dp_priv->ctrl->push_idle(dp_priv->ctrl); + break; + default: + pr_err("conn %d dpms set to unrecognized mode %d\n", + connector->base.id, power_mode); + break; + } + return rc; +} + static int dp_display_config_hdr(struct dp_display *dp_display, struct drm_msm_ext_hdr_metadata *hdr) { diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h index c980d9dbf5f2..e31a1645080d 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.h +++ b/drivers/gpu/drm/msm/dp/dp_display.h @@ -63,4 +63,6 @@ bool dp_connector_mode_needs_full_range(void *display); bool dp_connector_mode_is_cea_mode(void *display); enum sde_csc_type dp_connector_get_csc_type(struct drm_connector *conn, void *data); +int dp_display_set_power(struct drm_connector *connector, + int power_mode, void *display); #endif /* _DP_DISPLAY_H_ */ diff --git a/drivers/gpu/drm/msm/dp/dp_link.c b/drivers/gpu/drm/msm/dp/dp_link.c index 410e0754ebf5..3ebac9001c0f 100644 --- a/drivers/gpu/drm/msm/dp/dp_link.c +++ b/drivers/gpu/drm/msm/dp/dp_link.c @@ -17,6 +17,8 @@ #include "dp_link.h" #include "dp_panel.h" +#include + enum dynamic_range { DP_DYNAMIC_RANGE_RGB_VESA = 0x00, DP_DYNAMIC_RANGE_RGB_CEA = 0x01, @@ -961,9 +963,15 @@ static int dp_link_psm_config(struct dp_link *dp_link, link = container_of(dp_link, struct dp_link_private, dp_link); - if (enable) - ret = drm_dp_link_power_down(link->aux->drm_aux, link_info); - else + if (enable) { + if (dp_link->power_mode != DRM_MODE_DPMS_STANDBY + && dp_link->power_mode != DRM_MODE_DPMS_SUSPEND) + ret = drm_dp_link_power_down(link->aux->drm_aux, + link_info); + else + ret = drm_dp_link_power_down_aux_up(link->aux->drm_aux, + link_info); + } else ret = drm_dp_link_power_up(link->aux->drm_aux, link_info); if (ret) diff --git a/drivers/gpu/drm/msm/dp/dp_link.h b/drivers/gpu/drm/msm/dp/dp_link.h index d14b88155444..53edda03eaa5 100644 --- a/drivers/gpu/drm/msm/dp/dp_link.h +++ b/drivers/gpu/drm/msm/dp/dp_link.h @@ -109,6 +109,7 @@ static inline char *dp_link_get_test_name(u32 test_requested) struct dp_link { u32 sink_request; u32 test_response; + int power_mode; struct dp_link_sink_count sink_count; struct dp_link_test_video test_video; diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c index 4b006c59fee3..43f011de5113 100644 --- a/drivers/gpu/drm/msm/dp/dp_panel.c +++ b/drivers/gpu/drm/msm/dp/dp_panel.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -22,6 +22,7 @@ #define DP_MAX_DS_PORT_COUNT 1 #define DPRX_FEATURE_ENUMERATION_LIST 0x2210 +#define DPRX_EXTENDED_DPCD_FIELD 0x2200 #define VSC_SDP_EXTENSION_FOR_COLORIMETRY_SUPPORTED BIT(3) #define VSC_EXT_VESA_SDP_SUPPORTED BIT(4) #define VSC_EXT_VESA_SDP_CHAINING_SUPPORTED BIT(5) @@ -122,8 +123,9 @@ static int dp_panel_read_dpcd(struct dp_panel *dp_panel, bool multi_func) int rlen, rc = 0; struct dp_panel_private *panel; struct drm_dp_link *link_info; - u8 *dpcd, rx_feature; - u32 dfp_count = 0; + struct drm_dp_aux *drm_aux; + u8 *dpcd, rx_feature, temp; + u32 dfp_count = 0, offset = DP_DPCD_REV; unsigned long caps = DP_LINK_CAP_ENHANCED_FRAMING; if (!dp_panel) { @@ -135,44 +137,64 @@ static int dp_panel_read_dpcd(struct dp_panel *dp_panel, bool multi_func) dpcd = dp_panel->dpcd; panel = container_of(dp_panel, struct dp_panel_private, dp_panel); + drm_aux = panel->aux->drm_aux; link_info = &dp_panel->link_info; - if (!panel->custom_dpcd) { - rlen = drm_dp_dpcd_read(panel->aux->drm_aux, DP_DPCD_REV, - dp_panel->dpcd, (DP_RECEIVER_CAP_SIZE + 1)); - if (rlen < (DP_RECEIVER_CAP_SIZE + 1)) { - pr_err("dpcd read failed, rlen=%d\n", rlen); - if (rlen == -ETIMEDOUT) - rc = rlen; - else - rc = -EINVAL; + /* reset vsc data */ + panel->vsc_supported = false; + panel->vscext_supported = false; + panel->vscext_chaining_supported = false; - goto end; - } + if (panel->custom_dpcd) { + pr_debug("skip dpcd read in debug mode\n"); + goto skip_dpcd_read; } + rlen = drm_dp_dpcd_read(drm_aux, DP_TRAINING_AUX_RD_INTERVAL, &temp, 1); + if (rlen != 1) { + pr_err("error reading DP_TRAINING_AUX_RD_INTERVAL\n"); + rc = -EINVAL; + goto end; + } + + /* check for EXTENDED_RECEIVER_CAPABILITY_FIELD_PRESENT */ + if (temp & BIT(7)) { + pr_debug("using EXTENDED_RECEIVER_CAPABILITY_FIELD\n"); + offset = DPRX_EXTENDED_DPCD_FIELD; + } + + rlen = drm_dp_dpcd_read(drm_aux, offset, + dp_panel->dpcd, (DP_RECEIVER_CAP_SIZE + 1)); + if (rlen < (DP_RECEIVER_CAP_SIZE + 1)) { + pr_err("dpcd read failed, rlen=%d\n", rlen); + if (rlen == -ETIMEDOUT) + rc = rlen; + else + rc = -EINVAL; + + goto end; + } + + print_hex_dump(KERN_DEBUG, "[drm-dp] SINK DPCD: ", + DUMP_PREFIX_NONE, 8, 1, dp_panel->dpcd, rlen, false); + rlen = drm_dp_dpcd_read(panel->aux->drm_aux, DPRX_FEATURE_ENUMERATION_LIST, &rx_feature, 1); if (rlen != 1) { pr_debug("failed to read DPRX_FEATURE_ENUMERATION_LIST\n"); - panel->vsc_supported = false; - panel->vscext_supported = false; - panel->vscext_chaining_supported = false; - } else { - panel->vsc_supported = !!(rx_feature & - VSC_SDP_EXTENSION_FOR_COLORIMETRY_SUPPORTED); - - panel->vscext_supported = !!(rx_feature & - VSC_EXT_VESA_SDP_SUPPORTED); - - panel->vscext_chaining_supported = !!(rx_feature & - VSC_EXT_VESA_SDP_CHAINING_SUPPORTED); + goto skip_dpcd_read; } + panel->vsc_supported = !!(rx_feature & + VSC_SDP_EXTENSION_FOR_COLORIMETRY_SUPPORTED); + panel->vscext_supported = !!(rx_feature & VSC_EXT_VESA_SDP_SUPPORTED); + panel->vscext_chaining_supported = !!(rx_feature & + VSC_EXT_VESA_SDP_CHAINING_SUPPORTED); pr_debug("vsc=%d, vscext=%d, vscext_chaining=%d\n", panel->vsc_supported, panel->vscext_supported, panel->vscext_chaining_supported); +skip_dpcd_read: link_info->revision = dp_panel->dpcd[DP_DPCD_REV]; panel->major = (link_info->revision >> 4) & 0x0f; @@ -271,6 +293,7 @@ static int dp_panel_set_edid(struct dp_panel *dp_panel, u8 *edid, panel->custom_edid = false; } + pr_debug("%d\n", panel->custom_edid); return 0; } @@ -295,6 +318,8 @@ static int dp_panel_set_dpcd(struct dp_panel *dp_panel, u8 *dpcd) panel->custom_dpcd = false; } + pr_debug("%d\n", panel->custom_dpcd); + return 0; } diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c index 381e43206037..6212fd62eb61 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.c +++ b/drivers/gpu/drm/msm/sde/sde_kms.c @@ -1314,6 +1314,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev, .get_info = dp_connector_get_info, .get_mode_info = dp_connector_get_mode_info, .post_open = dp_connector_post_open, + .set_power = dp_display_set_power, .check_status = NULL, .config_hdr = dp_connector_config_hdr, .cmd_transfer = NULL, diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index c4dd5b6305db..6c70d487e1dd 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1,4 +1,5 @@ /* Copyright (c) 2008-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2179,6 +2180,15 @@ static int memdesc_sg_virt(struct kgsl_memdesc *memdesc, unsigned long useraddr) ret = sg_alloc_table_from_pages(memdesc->sgt, pages, npages, 0, memdesc->size, GFP_KERNEL); + + if (ret) + goto out; + + ret = kgsl_cache_range_op(memdesc, 0, memdesc->size, + KGSL_CACHE_OP_FLUSH); + + if (ret) + sg_free_table(memdesc->sgt); out: if (ret) { for (i = 0; i < npages; i++) diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c index a506ff4676c4..f462a3179020 100644 --- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c @@ -124,6 +124,24 @@ static void __cam_isp_ctx_dump_state_monitor_array( } } +static int __cam_isp_ctx_dequeue_request(struct cam_context *ctx, + struct cam_ctx_request *req) +{ + struct cam_ctx_request *req_current; + struct cam_ctx_request *req_prev; + + spin_lock_bh(&ctx->lock); + list_for_each_entry_safe_reverse(req_current, req_prev, + &ctx->pending_req_list, list) { + if (req->request_id == req_current->request_id) { + list_del_init(&req_current->list); + break; + } + } + spin_unlock_bh(&ctx->lock); + return 0; +} + static int __cam_isp_ctx_enqueue_request_in_order( struct cam_context *ctx, struct cam_ctx_request *req) { @@ -2193,13 +2211,12 @@ static int __cam_isp_ctx_config_dev_in_top_state( add_req.dev_hdl = ctx->dev_hdl; add_req.req_id = req->request_id; add_req.skip_before_applying = 0; + __cam_isp_ctx_enqueue_request_in_order(ctx, req); rc = ctx->ctx_crm_intf->add_req(&add_req); if (rc) { CAM_ERR(CAM_ISP, "Add req failed: req id=%llu", req->request_id); - } else { - __cam_isp_ctx_enqueue_request_in_order( - ctx, req); + __cam_isp_ctx_dequeue_request(ctx, req); } } else { rc = -EINVAL; diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c index a5a3470a4839..9e8ca62a94ea 100644 --- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c @@ -721,10 +721,11 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv, } if ((packet->num_cmd_buf > 5) || !packet->num_patches || - !packet->num_io_configs) { - CAM_ERR(CAM_JPEG, "wrong number of cmd/patch info: %u %u", - packet->num_cmd_buf, - packet->num_patches); + !packet->num_io_configs || + (packet->num_io_configs > CAM_JPEG_IMAGE_MAX)) { + CAM_ERR(CAM_JPEG, "wrong number of cmd/patch info: %u %u %u", + packet->num_cmd_buf, packet->num_patches, + packet->num_io_configs); return -EINVAL; } diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c index 3837aac6a2e5..51375809b6e2 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c @@ -1,4 +1,5 @@ /* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -563,7 +564,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, rc = cam_sensor_i2c_command_parser( &a_ctrl->io_master_info, i2c_reg_settings, - &cmd_desc[i], 1); + &cmd_desc[i], 1, NULL); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, "Failed:parse init settings: %d", @@ -625,7 +626,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, rc = cam_sensor_i2c_command_parser( &a_ctrl->io_master_info, i2c_reg_settings, - cmd_desc, 1); + cmd_desc, 1, NULL); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, "Auto move lens parsing failed: %d", rc); @@ -656,7 +657,7 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl, rc = cam_sensor_i2c_command_parser( &a_ctrl->io_master_info, i2c_reg_settings, - cmd_desc, 1); + cmd_desc, 1, NULL); if (rc < 0) { CAM_ERR(CAM_ACTUATOR, "Manual move lens parsing failed: %d", rc); diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_core.c index 4302d4897ea9..47eb2022ea66 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_core.c @@ -1,4 +1,5 @@ /* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1079,7 +1080,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) rc = cam_sensor_i2c_command_parser( &fctrl->io_master_info, i2c_reg_settings, - &cmd_desc[i], 1); + &cmd_desc[i], 1, NULL); if (rc < 0) { CAM_ERR(CAM_FLASH, "pkt parsing failed: %d", rc); @@ -1159,7 +1160,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) cmd_desc = (struct cam_cmd_buf_desc *)(offset); rc = cam_sensor_i2c_command_parser( &fctrl->io_master_info, - i2c_reg_settings, cmd_desc, 1); + i2c_reg_settings, cmd_desc, 1, NULL); if (rc) { CAM_ERR(CAM_FLASH, "Failed in parsing i2c packets"); @@ -1190,7 +1191,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg) cmd_desc = (struct cam_cmd_buf_desc *)(offset); rc = cam_sensor_i2c_command_parser( &fctrl->io_master_info, - i2c_reg_settings, cmd_desc, 1); + i2c_reg_settings, cmd_desc, 1, NULL); if (rc) { CAM_ERR(CAM_FLASH, "Failed in parsing i2c NRT packets"); diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c index 711077cdfdf8..c8d3a1a0a49b 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c @@ -1,4 +1,5 @@ /* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -552,7 +553,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) rc = cam_sensor_i2c_command_parser( &o_ctrl->io_master_info, i2c_reg_settings, - &cmd_desc[i], 1); + &cmd_desc[i], 1, NULL); if (rc < 0) { CAM_ERR(CAM_OIS, "init parsing failed: %d", rc); @@ -569,7 +570,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) rc = cam_sensor_i2c_command_parser( &o_ctrl->io_master_info, i2c_reg_settings, - &cmd_desc[i], 1); + &cmd_desc[i], 1, NULL); if (rc < 0) { CAM_ERR(CAM_OIS, "Calib parsing failed: %d", rc); @@ -644,7 +645,7 @@ static int cam_ois_pkt_parse(struct cam_ois_ctrl_t *o_ctrl, void *arg) i2c_reg_settings->request_id = 0; rc = cam_sensor_i2c_command_parser(&o_ctrl->io_master_info, i2c_reg_settings, - cmd_desc, 1); + cmd_desc, 1, NULL); if (rc < 0) { CAM_ERR(CAM_OIS, "OIS pkt parsing failed: %d", rc); goto rel_pkt; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c index 94bc611a9120..0ed36d143265 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -1,4 +1,5 @@ /* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -94,6 +95,7 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl, struct cam_control *ioctl_ctrl = NULL; struct cam_packet *csl_packet = NULL; struct cam_cmd_buf_desc *cmd_desc = NULL; + struct cam_buf_io_cfg *io_cfg = NULL; struct i2c_settings_array *i2c_reg_settings = NULL; size_t len_of_buff = 0; size_t remain_len = 0; @@ -194,7 +196,27 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl, i2c_reg_settings->is_settings_valid = 1; break; } + case CAM_SENSOR_PACKET_OPCODE_SENSOR_READ: { + i2c_reg_settings = &(i2c_data->read_settings); + i2c_reg_settings->request_id = 0; + i2c_reg_settings->is_settings_valid = 1; + CAM_DBG(CAM_SENSOR, "number of IO configs: %d:", + csl_packet->num_io_configs); + if (csl_packet->num_io_configs == 0) { + CAM_ERR(CAM_SENSOR, "No I/O configs to process"); + goto rel_pkt_buf; + } + io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *) + &csl_packet->payload + + csl_packet->io_configs_offset); + + if (io_cfg == NULL) { + CAM_ERR(CAM_SENSOR, "I/O config is invalid(NULL)"); + goto rel_pkt_buf; + } + break; + } case CAM_SENSOR_PACKET_OPCODE_SENSOR_UPDATE: { if ((s_ctrl->sensor_state == CAM_SENSOR_INIT) || (s_ctrl->sensor_state == CAM_SENSOR_ACQUIRE)) { @@ -246,7 +268,7 @@ static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl, cmd_desc = (struct cam_cmd_buf_desc *)(offset); rc = cam_sensor_i2c_command_parser(&s_ctrl->io_master_info, - i2c_reg_settings, cmd_desc, 1); + i2c_reg_settings, cmd_desc, 1, io_cfg); if (rc < 0) { CAM_ERR(CAM_SENSOR, "Fail parsing I2C Pkt: %d", rc); goto rel_pkt_buf; @@ -323,7 +345,6 @@ static int32_t cam_sensor_i2c_modes_util( } } } - return rc; } @@ -986,6 +1007,25 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, } s_ctrl->sensor_state = CAM_SENSOR_CONFIG; } + + if (s_ctrl->i2c_data.read_settings.is_settings_valid) { + rc = cam_sensor_i2c_read_data( + &s_ctrl->i2c_data.read_settings, + &s_ctrl->io_master_info); + if (rc < 0) { + CAM_ERR(CAM_SENSOR, "cannot read data: %d", rc); + delete_request(&s_ctrl->i2c_data.read_settings); + goto release_mutex; + } + rc = delete_request( + &s_ctrl->i2c_data.read_settings); + if (rc < 0) { + CAM_ERR(CAM_SENSOR, + "Fail in deleting the read settings"); + goto release_mutex; + } + } + } break; default: diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_dev.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_dev.c index 5c5c97099d43..3e5e6b9982b6 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_dev.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_dev.c @@ -1,4 +1,5 @@ /* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -187,6 +188,7 @@ static int32_t cam_sensor_driver_i2c_probe(struct i2c_client *client, INIT_LIST_HEAD(&(s_ctrl->i2c_data.config_settings.list_head)); INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamon_settings.list_head)); INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamoff_settings.list_head)); + INIT_LIST_HEAD(&(s_ctrl->i2c_data.read_settings.list_head)); for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) INIT_LIST_HEAD(&(s_ctrl->i2c_data.per_frame[i].list_head)); @@ -323,6 +325,7 @@ static int32_t cam_sensor_driver_platform_probe( INIT_LIST_HEAD(&(s_ctrl->i2c_data.config_settings.list_head)); INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamon_settings.list_head)); INIT_LIST_HEAD(&(s_ctrl->i2c_data.streamoff_settings.list_head)); + INIT_LIST_HEAD(&(s_ctrl->i2c_data.read_settings.list_head)); for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) INIT_LIST_HEAD(&(s_ctrl->i2c_data.per_frame[i].list_head)); diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h index 7a2c56e3b686..87cf5734e60e 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h @@ -1,4 +1,5 @@ /* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -159,6 +160,7 @@ enum cam_sensor_packet_opcodes { CAM_SENSOR_PACKET_OPCODE_SENSOR_PROBE, CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG, CAM_SENSOR_PACKET_OPCODE_SENSOR_STREAMOFF, + CAM_SENSOR_PACKET_OPCODE_SENSOR_READ, CAM_SENSOR_PACKET_OPCODE_SENSOR_NOP = 127 }; @@ -224,7 +226,8 @@ enum cam_sensor_i2c_cmd_type { CAM_SENSOR_I2C_WRITE_RANDOM, CAM_SENSOR_I2C_WRITE_BURST, CAM_SENSOR_I2C_WRITE_SEQ, - CAM_SENSOR_I2C_READ, + CAM_SENSOR_I2C_READ_RANDOM, + CAM_SENSOR_I2C_READ_SEQ, CAM_SENSOR_I2C_POLL }; @@ -275,6 +278,8 @@ struct cam_sensor_i2c_reg_setting { enum camera_sensor_i2c_type addr_type; enum camera_sensor_i2c_type data_type; unsigned short delay; + uint8_t *read_buff; + uint32_t read_buff_len; }; struct i2c_settings_list { @@ -294,6 +299,7 @@ struct i2c_data_settings { struct i2c_settings_array config_settings; struct i2c_settings_array streamon_settings; struct i2c_settings_array streamoff_settings; + struct i2c_settings_array read_settings; struct i2c_settings_array *per_frame; }; diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c index 4d314964effd..a9bf591bbd6a 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c @@ -1,4 +1,5 @@ /* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -241,6 +242,143 @@ static int32_t cam_sensor_handle_continuous_write( return rc; } +static int32_t cam_sensor_get_io_buffer( + struct cam_buf_io_cfg *io_cfg, + struct cam_sensor_i2c_reg_setting *i2c_settings) +{ + uintptr_t buf_addr = 0x0; + size_t buf_size = 0; + int32_t rc = 0; + + if (io_cfg == NULL || i2c_settings == NULL) { + CAM_ERR(CAM_SENSOR, + "Invalid args, io buf or i2c settings is NULL"); + return -EINVAL; + } + + if (io_cfg->direction == CAM_BUF_OUTPUT) { + rc = cam_mem_get_cpu_buf(io_cfg->mem_handle[0], + &buf_addr, &buf_size); + if ((rc < 0) || (!buf_addr)) { + CAM_ERR(CAM_SENSOR, + "invalid buffer, rc: %d, buf_addr: %pK", + rc, (void *)buf_addr); + return -EINVAL; + } + CAM_DBG(CAM_SENSOR, + "buf_addr: %pK, buf_size: %zu, offsetsize: %d", + (void *)buf_addr, buf_size, io_cfg->offsets[0]); + if (io_cfg->offsets[0] >= buf_size) { + CAM_ERR(CAM_SENSOR, + "invalid size:io_cfg->offsets[0]: %d, buf_size: %d", + io_cfg->offsets[0], (unsigned int)buf_size); + return -EINVAL; + } + i2c_settings->read_buff = + (uint8_t *)buf_addr + io_cfg->offsets[0]; + i2c_settings->read_buff_len = + buf_size - io_cfg->offsets[0]; + } else { + CAM_ERR(CAM_SENSOR, "Invalid direction: %d", + io_cfg->direction); + rc = -EINVAL; + } + return rc; +} + +static int32_t cam_sensor_handle_random_read( + struct cam_cmd_i2c_random_rd *cmd_i2c_random_rd, + struct i2c_settings_array *i2c_reg_settings, + uint16_t *cmd_length_in_bytes, + int32_t *offset, + struct list_head **list, + struct cam_buf_io_cfg *io_cfg) +{ + struct i2c_settings_list *i2c_list; + int32_t rc = 0, cnt = 0; + + i2c_list = cam_sensor_get_i2c_ptr(i2c_reg_settings, + cmd_i2c_random_rd->header.count); + if ((i2c_list == NULL) || + (i2c_list->i2c_settings.reg_setting == NULL)) { + CAM_ERR(CAM_SENSOR, + "Failed in allocating i2c_list: %pK", + i2c_list); + return -ENOMEM; + } + + rc = cam_sensor_get_io_buffer(io_cfg, &(i2c_list->i2c_settings)); + if (rc) { + CAM_ERR(CAM_SENSOR, "Failed to get read buffer: %d", rc); + } else { + *cmd_length_in_bytes = sizeof(struct i2c_rdwr_header) + + (sizeof(struct cam_cmd_read) * + (cmd_i2c_random_rd->header.count)); + i2c_list->op_code = CAM_SENSOR_I2C_READ_RANDOM; + i2c_list->i2c_settings.addr_type = + cmd_i2c_random_rd->header.addr_type; + i2c_list->i2c_settings.data_type = + cmd_i2c_random_rd->header.data_type; + i2c_list->i2c_settings.size = + cmd_i2c_random_rd->header.count; + + for (cnt = 0; cnt < (cmd_i2c_random_rd->header.count); + cnt++) { + i2c_list->i2c_settings.reg_setting[cnt].reg_addr = + cmd_i2c_random_rd->data_read[cnt].reg_data; + } + *offset = cnt; + *list = &(i2c_list->list); + } + + return rc; +} + +static int32_t cam_sensor_handle_continuous_read( + struct cam_cmd_i2c_continuous_rd *cmd_i2c_continuous_rd, + struct i2c_settings_array *i2c_reg_settings, + uint16_t *cmd_length_in_bytes, int32_t *offset, + struct list_head **list, + struct cam_buf_io_cfg *io_cfg) +{ + struct i2c_settings_list *i2c_list; + int32_t rc = 0, cnt = 0; + + i2c_list = cam_sensor_get_i2c_ptr(i2c_reg_settings, 1); + if ((i2c_list == NULL) || + (i2c_list->i2c_settings.reg_setting == NULL)) { + CAM_ERR(CAM_SENSOR, + "Failed in allocating i2c_list: %pK", + i2c_list); + return -ENOMEM; + } + + rc = cam_sensor_get_io_buffer(io_cfg, &(i2c_list->i2c_settings)); + if (rc) { + CAM_ERR(CAM_SENSOR, + "Failed to get read buffer: %d %d", rc, cnt); + } else { + + *cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_continuous_rd); + i2c_list->op_code = CAM_SENSOR_I2C_READ_SEQ; + + i2c_list->i2c_settings.addr_type = + cmd_i2c_continuous_rd->header.addr_type; + i2c_list->i2c_settings.data_type = + cmd_i2c_continuous_rd->header.data_type; + i2c_list->i2c_settings.size = + cmd_i2c_continuous_rd->header.count; + i2c_list->i2c_settings.reg_setting[0].reg_addr = + cmd_i2c_continuous_rd->reg_addr; + + *offset = cnt; + *list = &(i2c_list->list); + } + + return rc; +} + + static int cam_sensor_handle_slave_info( struct camera_io_master *io_master, uint32_t *cmd_buf) @@ -291,7 +429,8 @@ int cam_sensor_i2c_command_parser( struct camera_io_master *io_master, struct i2c_settings_array *i2c_reg_settings, struct cam_cmd_buf_desc *cmd_desc, - int32_t num_cmd_buffers) + int32_t num_cmd_buffers, + struct cam_buf_io_cfg *io_cfg) { int16_t rc = 0, i = 0; size_t len_of_buff = 0; @@ -496,6 +635,92 @@ int cam_sensor_i2c_command_parser( byte_cnt += cmd_length_in_bytes; break; } + case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_RD: { + uint16_t cmd_length_in_bytes = 0; + struct cam_cmd_i2c_random_rd *i2c_random_rd = + (struct cam_cmd_i2c_random_rd *)cmd_buf; + + if (remain_len - byte_cnt < + sizeof(struct cam_cmd_i2c_random_rd)) { + CAM_ERR(CAM_SENSOR, + "Not enough buffer space"); + rc = -EINVAL; + goto rel_buf; + } + + tot_size = sizeof(struct i2c_rdwr_header) + + (sizeof(struct cam_cmd_read) * + i2c_random_rd->header.count); + + if (tot_size > (remain_len - byte_cnt)) { + CAM_ERR(CAM_SENSOR, + "Not enough buff provided %x, %x, %d", + (unsigned int)tot_size, + (unsigned int)remain_len, + byte_cnt); + rc = -EINVAL; + goto rel_buf; + } + + rc = cam_sensor_handle_random_read( + i2c_random_rd, + i2c_reg_settings, + &cmd_length_in_bytes, &j, &list, + io_cfg); + if (rc < 0) { + CAM_ERR(CAM_SENSOR, + "Failed in random read %d", rc); + goto end; + } + + cmd_buf += cmd_length_in_bytes / + sizeof(uint32_t); + byte_cnt += cmd_length_in_bytes; + break; + } + case CAMERA_SENSOR_CMD_TYPE_I2C_CONT_RD: { + uint16_t cmd_length_in_bytes = 0; + struct cam_cmd_i2c_continuous_rd + *i2c_continuous_rd = + (struct cam_cmd_i2c_continuous_rd *)cmd_buf; + + if (remain_len - byte_cnt < + sizeof(struct cam_cmd_i2c_continuous_rd)) { + CAM_ERR(CAM_SENSOR, + "Not enough buffer space"); + rc = -EINVAL; + goto end; + } + + tot_size = + sizeof(struct cam_cmd_i2c_continuous_rd); + + if (tot_size > (remain_len - byte_cnt)) { + CAM_ERR(CAM_SENSOR, + "Not enough buff provided %d, %d, %d", + (int)tot_size, (int)remain_len, + byte_cnt); + rc = -EINVAL; + goto end; + } + + rc = cam_sensor_handle_continuous_read( + i2c_continuous_rd, + i2c_reg_settings, + &cmd_length_in_bytes, &j, &list, + io_cfg); + if (rc < 0) { + CAM_ERR(CAM_SENSOR, + "Failed in continuous read %d", rc); + goto end; + } + + cmd_buf += cmd_length_in_bytes / + sizeof(uint32_t); + byte_cnt += cmd_length_in_bytes; + break; + } + default: CAM_ERR(CAM_SENSOR, "Invalid Command Type:%d", cmm_hdr->cmd_type); @@ -508,7 +733,7 @@ int cam_sensor_i2c_command_parser( CAM_WARN(CAM_SENSOR, "put failed for buffer :%d", cmd_desc[i].mem_handle); } - +end: return rc; rel_buf: @@ -587,6 +812,93 @@ int cam_sensor_util_i2c_apply_setting( return rc; } +int32_t cam_sensor_i2c_read_data( + struct i2c_settings_array *i2c_settings, + struct camera_io_master *io_master_info) +{ + int32_t rc = 0; + struct i2c_settings_list *i2c_list; + uint32_t cnt = 0; + uint8_t *read_buff = NULL; + uint32_t buff_length = 0; + uint32_t read_length = 0; + + list_for_each_entry(i2c_list, + &(i2c_settings->list_head), list) { + read_buff = i2c_list->i2c_settings.read_buff; + buff_length = i2c_list->i2c_settings.read_buff_len; + if ((read_buff == NULL) || (buff_length == 0)) { + CAM_ERR(CAM_SENSOR, + "Invalid input buffer, buffer: %pK, length: %d", + read_buff, buff_length); + return -EINVAL; + } + + if (i2c_list->op_code == CAM_SENSOR_I2C_READ_RANDOM) { + read_length = i2c_list->i2c_settings.data_type * + i2c_list->i2c_settings.size; + if ((read_length > buff_length) || + (read_length < + i2c_list->i2c_settings.size)) { + CAM_ERR(CAM_SENSOR, + "Invalid size, readLen:%d, bufLen:%d, size:%d", + read_length, buff_length, + i2c_list->i2c_settings.size); + return -EINVAL; + } + for (cnt = 0; cnt < (i2c_list->i2c_settings.size); + cnt++) { + struct cam_sensor_i2c_reg_array *reg_setting = + &(i2c_list->i2c_settings.reg_setting[cnt]); + rc = camera_io_dev_read(io_master_info, + reg_setting->reg_addr, + ®_setting->reg_data, + i2c_list->i2c_settings.addr_type, + i2c_list->i2c_settings.data_type); + if (rc < 0) { + CAM_ERR(CAM_SENSOR, + "Failed: random read I2C settings: %d", + rc); + return rc; + } + if (i2c_list->i2c_settings.data_type < + CAMERA_SENSOR_I2C_TYPE_MAX) { + memcpy(read_buff, + ®_setting->reg_data, + i2c_list->i2c_settings.data_type); + read_buff += + i2c_list->i2c_settings.data_type; + } + } + } else if (i2c_list->op_code == CAM_SENSOR_I2C_READ_SEQ) { + read_length = i2c_list->i2c_settings.size; + if (read_length > buff_length) { + CAM_ERR(CAM_SENSOR, + "Invalid buffer size,readLen: %d, bufLen:%d", + read_length, buff_length); + return -EINVAL; + } + rc = camera_io_dev_read_seq( + io_master_info, + i2c_list->i2c_settings.reg_setting[0].reg_addr, + read_buff, + i2c_list->i2c_settings.addr_type, + i2c_list->i2c_settings.data_type, + i2c_list->i2c_settings.size); + if (rc < 0) { + CAM_ERR(CAM_SENSOR, + "failed: seq read I2C settings: %d", + rc); + return rc; + } + } + } + + return rc; +} + + + int32_t msm_camera_fill_vreg_params( struct cam_hw_soc_info *soc_info, struct cam_sensor_power_setting *power_setting, diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h index 85497fda011c..b8cc41c0d215 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h @@ -1,4 +1,5 @@ /* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -28,6 +29,10 @@ #define INVALID_VREG 100 +int32_t cam_sensor_i2c_read_data( + struct i2c_settings_array *i2c_settings, + struct camera_io_master *io_master_info); + int cam_get_dt_power_setting_data(struct device_node *of_node, struct cam_hw_soc_info *soc_info, struct cam_sensor_power_ctrl_t *power_info); @@ -37,7 +42,9 @@ int msm_camera_pinctrl_init int cam_sensor_i2c_command_parser(struct camera_io_master *io_master, struct i2c_settings_array *i2c_reg_settings, - struct cam_cmd_buf_desc *cmd_desc, int32_t num_cmd_buffers); + struct cam_cmd_buf_desc *cmd_desc, int32_t num_cmd_buffers, + struct cam_buf_io_cfg *io_cfg); + int cam_sensor_util_i2c_apply_setting(struct camera_io_master *io_master_info, struct i2c_settings_list *i2c_list); diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c b/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c index 793d13c003cf..30a2d28b4bb3 100644 --- a/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c +++ b/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c @@ -428,6 +428,7 @@ static int ipa_uc_ntn_alloc_conn_smmu_info(struct ipa_ntn_setup_info *dest, source->buff_pool_base_sgt); if (result) { kfree(dest->data_buff_list); + dest->data_buff_list = NULL; return result; } @@ -435,6 +436,7 @@ static int ipa_uc_ntn_alloc_conn_smmu_info(struct ipa_ntn_setup_info *dest, source->ring_base_sgt); if (result) { kfree(dest->data_buff_list); + dest->data_buff_list = NULL; ipa_smmu_free_sgt(&dest->buff_pool_base_sgt); return result; } @@ -445,6 +447,7 @@ static int ipa_uc_ntn_alloc_conn_smmu_info(struct ipa_ntn_setup_info *dest, static void ipa_uc_ntn_free_conn_smmu_info(struct ipa_ntn_setup_info *params) { kfree(params->data_buff_list); + params->data_buff_list = NULL; ipa_smmu_free_sgt(¶ms->buff_pool_base_sgt); ipa_smmu_free_sgt(¶ms->ring_base_sgt); } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index ec298bbcb97e..1e03e6d9f464 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -344,6 +344,7 @@ static void ipa3_active_clients_log_destroy(void) kfree(active_clients_table_buf); active_clients_table_buf = NULL; kfree(ipa3_ctx->ipa3_active_clients_logging.log_buffer[0]); + ipa3_ctx->ipa3_active_clients_logging.log_buffer[0] = NULL; ipa3_ctx->ipa3_active_clients_logging.log_head = 0; ipa3_ctx->ipa3_active_clients_logging.log_tail = IPA3_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES - 1; @@ -5861,8 +5862,10 @@ fail_bus_reg: fail_init_mem_partition: fail_bind: kfree(ipa3_ctx->ctrl); + ipa3_ctx->ctrl = NULL; fail_mem_ctrl: kfree(ipa3_ctx->ipa_tz_unlock_reg); + ipa3_ctx->ipa_tz_unlock_reg = NULL; fail_tz_unlock_reg: if (ipa3_ctx->logbuf) ipc_log_context_destroy(ipa3_ctx->logbuf); @@ -6240,6 +6243,7 @@ static int get_ipa_dts_configuration(struct platform_device *pdev, IPAERR("failed to read register addresses\n"); kfree(ipa_tz_unlock_reg); kfree(ipa_drv_res->ipa_tz_unlock_reg); + ipa_drv_res->ipa_tz_unlock_reg = NULL; return -EFAULT; } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c index 1ab4934774e3..3df8f49e5f0b 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c @@ -982,7 +982,7 @@ static int __ipa_del_flt_rule(u32 rule_hdl) list_del(&entry->link); entry->tbl->rule_cnt--; - if (entry->rt_tbl) + if (entry->rt_tbl && !ipa3_check_idr_if_freed(entry->rt_tbl)) entry->rt_tbl->ref_cnt--; IPADBG("del flt rule rule_cnt=%d rule_id=%d\n", entry->tbl->rule_cnt, entry->rule_id); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_pm.c b/drivers/platform/msm/ipa/ipa_v3/ipa_pm.c index e244a19fcd4e..1e7a06509cdc 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_pm.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_pm.c @@ -617,6 +617,7 @@ int ipa_pm_init(struct ipa_pm_init_params *params) if (!ipa_pm_ctx->wq) { IPA_PM_ERR("create workqueue failed\n"); kfree(ipa_pm_ctx); + ipa_pm_ctx = NULL; return -ENOMEM; } diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c index 0a2274ca9eef..fb6b49552742 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c @@ -599,6 +599,7 @@ static void ipa_release_uc_smmu_mappings(enum ipa_client_type client) ipa3_ctx->wdi_map_cnt--; } kfree(wdi_res[i].res); + wdi_res[i].res = NULL; wdi_res[i].valid = false; } } diff --git a/drivers/staging/android/ion/msm/msm_ion.c b/drivers/staging/android/ion/msm/msm_ion.c index 12186066c999..8740b3339862 100644 --- a/drivers/staging/android/ion/msm/msm_ion.c +++ b/drivers/staging/android/ion/msm/msm_ion.c @@ -637,6 +637,9 @@ static int check_vaddr_bounds(unsigned long start, unsigned long end) struct vm_area_struct *vma; int ret = 1; + if (!start) + goto out; + if (end < start) goto out; @@ -834,20 +837,28 @@ long msm_ion_custom_ioctl(struct ion_client *client, down_read(&mm->mmap_sem); - start = (unsigned long)data.flush_data.vaddr + - data.flush_data.offset; - end = start + data.flush_data.length; - - if (start && check_vaddr_bounds(start, end)) { - pr_err("%s: virtual address %pK is out of bounds\n", + if ((unsigned long)data.flush_data.vaddr > + (ULONG_MAX - data.flush_data.offset)) { + pr_err("%s: Integer overflow detected for %pK\n", __func__, data.flush_data.vaddr); ret = -EINVAL; } else { - ret = ion_do_cache_op( - client, handle, data.flush_data.vaddr, - data.flush_data.offset, - data.flush_data.length, cmd); + start = (unsigned long)data.flush_data.vaddr + + data.flush_data.offset; + end = start + data.flush_data.length; + + if (check_vaddr_bounds(start, end)) { + pr_err("%s: virtual address %pK is out of bounds\n", + __func__, data.flush_data.vaddr); + ret = -EINVAL; + } else { + ret = ion_do_cache_op( + client, handle, data.flush_data.vaddr, + data.flush_data.offset, + data.flush_data.length, cmd); + } } + up_read(&mm->mmap_sem); ion_free_nolock(client, handle); diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 4d8f7a104137..67175f22cec4 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -536,7 +536,8 @@ #define DP_SET_POWER 0x600 # define DP_SET_POWER_D0 0x1 # define DP_SET_POWER_D3 0x2 -# define DP_SET_POWER_MASK 0x3 +#define DP_SET_POWER_D5 0x5 +# define DP_SET_POWER_MASK 0x7 #define DP_EDP_DPCD_REV 0x700 /* eDP 1.2 */ # define DP_EDP_11 0x00 @@ -983,6 +984,8 @@ struct drm_dp_link { int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link); +int drm_dp_link_power_down_aux_up(struct drm_dp_aux *aux, + struct drm_dp_link *link); int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link); int drm_dp_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE], const u8 port_cap[4]); diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 3c4d7d0b8163..0d83cd736900 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2607,7 +2607,7 @@ sub process { $qca_sign_off = 1; } elsif ($line =~ /^\s*signed-off-by:.*codeaurora\.org/i) { $codeaurora_sign_off = 1; - } elsif ($line =~ /^\s*signed-off-by:.*(quicinc|qualcomm)\.com/i) { + } elsif ($line =~ /^\s*signed-off-by:.*qualcomm\.com/i) { WARN("BAD_SIGN_OFF", "invalid Signed-off-by identity\n" . $line ); } @@ -2746,7 +2746,7 @@ sub process { #check the patch for invalid author credentials if ($chk_author && !($line =~ /^From:.*qca\.qualcomm\.com/) && - $line =~ /^From:.*(quicinc|qualcomm)\.com/) { + $line =~ /^From:.*qualcomm\.com/) { WARN("BAD_AUTHOR", "invalid author identity\n" . $line ); }