From e2c3e6f53a7a8a00ffeed127cfd1b397c3b016f8 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 10 Mar 2023 15:53:44 +0100 Subject: mac802154: Handle active scanning Active scan support is based on the current passive scan support, cheered up with beacon requests sent after every channel change. Co-developed-by: David Girault Signed-off-by: David Girault Signed-off-by: Miquel Raynal Acked-by: Alexander Aring Link: https://lore.kernel.org/r/20230310145346.1397068-3-miquel.raynal@bootlin.com Signed-off-by: Stefan Schmidt --- include/net/ieee802154_netdev.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index da8a3e648c7a..257c9b2e9c9a 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h @@ -74,6 +74,10 @@ struct ieee802154_beacon_hdr { #endif } __packed; +struct ieee802154_mac_cmd_pl { + u8 cmd_id; +} __packed; + struct ieee802154_sechdr { #if defined(__LITTLE_ENDIAN_BITFIELD) u8 level:3, @@ -149,6 +153,16 @@ struct ieee802154_beacon_frame { struct ieee802154_beacon_hdr mac_pl; }; +struct ieee802154_mac_cmd_frame { + struct ieee802154_hdr mhr; + struct ieee802154_mac_cmd_pl mac_pl; +}; + +struct ieee802154_beacon_req_frame { + struct ieee802154_hdr mhr; + struct ieee802154_mac_cmd_pl mac_pl; +}; + /* pushes hdr onto the skb. fields of hdr->fc that can be calculated from * the contents of hdr will be, and the actual value of those bits in * hdr->fc will be ignored. this includes the INTRA_PAN bit and the frame @@ -174,9 +188,11 @@ int ieee802154_hdr_peek_addrs(const struct sk_buff *skb, */ int ieee802154_hdr_peek(const struct sk_buff *skb, struct ieee802154_hdr *hdr); -/* pushes a beacon frame into an skb */ +/* pushes/pulls various frame types into/from an skb */ int ieee802154_beacon_push(struct sk_buff *skb, struct ieee802154_beacon_frame *beacon); +int ieee802154_mac_cmd_push(struct sk_buff *skb, void *frame, + const void *pl, unsigned int pl_len); int ieee802154_max_payload(const struct ieee802154_hdr *hdr); -- cgit v1.2.3 From d021d218f6d924ff5417c64b2e41d184e4bb32d3 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 10 Mar 2023 15:53:46 +0100 Subject: mac802154: Handle received BEACON_REQ When performing an active scan, devices emit BEACON_REQ which must be answered by other PANs receiving the request, unless they are already passively sending beacons. Answering a beacon request becomes a duty when the user tells us to send beacons and the request provides an interval of 15. Signed-off-by: Miquel Raynal Acked-by: Alexander Aring Link: https://lore.kernel.org/r/20230310145346.1397068-5-miquel.raynal@bootlin.com Signed-off-by: Stefan Schmidt --- include/net/ieee802154_netdev.h | 2 ++ net/ieee802154/header_ops.c | 13 ++++++++ net/mac802154/ieee802154_i.h | 20 ++++++++++++ net/mac802154/main.c | 2 ++ net/mac802154/rx.c | 70 ++++++++++++++++++++++++++++++++++++++++- net/mac802154/scan.c | 15 ++++++--- 6 files changed, 117 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index 257c9b2e9c9a..063313df447d 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h @@ -193,6 +193,8 @@ int ieee802154_beacon_push(struct sk_buff *skb, struct ieee802154_beacon_frame *beacon); int ieee802154_mac_cmd_push(struct sk_buff *skb, void *frame, const void *pl, unsigned int pl_len); +int ieee802154_mac_cmd_pl_pull(struct sk_buff *skb, + struct ieee802154_mac_cmd_pl *mac_pl); int ieee802154_max_payload(const struct ieee802154_hdr *hdr); diff --git a/net/ieee802154/header_ops.c b/net/ieee802154/header_ops.c index a5ff1017a4b2..41a556be1017 100644 --- a/net/ieee802154/header_ops.c +++ b/net/ieee802154/header_ops.c @@ -307,6 +307,19 @@ ieee802154_hdr_pull(struct sk_buff *skb, struct ieee802154_hdr *hdr) } EXPORT_SYMBOL_GPL(ieee802154_hdr_pull); +int ieee802154_mac_cmd_pl_pull(struct sk_buff *skb, + struct ieee802154_mac_cmd_pl *mac_pl) +{ + if (!pskb_may_pull(skb, sizeof(*mac_pl))) + return -EINVAL; + + memcpy(mac_pl, skb->data, sizeof(*mac_pl)); + skb_pull(skb, sizeof(*mac_pl)); + + return 0; +} +EXPORT_SYMBOL_GPL(ieee802154_mac_cmd_pl_pull); + int ieee802154_hdr_peek_addrs(const struct sk_buff *skb, struct ieee802154_hdr *hdr) { diff --git a/net/mac802154/ieee802154_i.h b/net/mac802154/ieee802154_i.h index 7bfd5411a164..c347ec9ff8c9 100644 --- a/net/mac802154/ieee802154_i.h +++ b/net/mac802154/ieee802154_i.h @@ -71,6 +71,8 @@ struct ieee802154_local { /* Asynchronous tasks */ struct list_head rx_beacon_list; struct work_struct rx_beacon_work; + struct list_head rx_mac_cmd_list; + struct work_struct rx_mac_cmd_work; bool started; bool suspended; @@ -155,6 +157,22 @@ ieee802154_sdata_running(struct ieee802154_sub_if_data *sdata) return test_bit(SDATA_STATE_RUNNING, &sdata->state); } +static inline int ieee802154_get_mac_cmd(struct sk_buff *skb, u8 *mac_cmd) +{ + struct ieee802154_mac_cmd_pl mac_pl; + int ret; + + if (mac_cb(skb)->type != IEEE802154_FC_TYPE_MAC_CMD) + return -EINVAL; + + ret = ieee802154_mac_cmd_pl_pull(skb, &mac_pl); + if (ret) + return ret; + + *mac_cmd = mac_pl.cmd_id; + return 0; +} + extern struct ieee802154_mlme_ops mac802154_mlme_wpan; void ieee802154_rx(struct ieee802154_local *local, struct sk_buff *skb); @@ -276,6 +294,8 @@ static inline bool mac802154_is_beaconing(struct ieee802154_local *local) return test_bit(IEEE802154_IS_BEACONING, &local->ongoing); } +void mac802154_rx_mac_cmd_worker(struct work_struct *work); + /* interface handling */ int ieee802154_iface_init(void); void ieee802154_iface_exit(void); diff --git a/net/mac802154/main.c b/net/mac802154/main.c index ee23e234b998..357ece67432b 100644 --- a/net/mac802154/main.c +++ b/net/mac802154/main.c @@ -90,6 +90,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops) INIT_LIST_HEAD(&local->interfaces); INIT_LIST_HEAD(&local->rx_beacon_list); + INIT_LIST_HEAD(&local->rx_mac_cmd_list); mutex_init(&local->iflist_mtx); tasklet_setup(&local->tasklet, ieee802154_tasklet_handler); @@ -100,6 +101,7 @@ ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops) INIT_DELAYED_WORK(&local->scan_work, mac802154_scan_worker); INIT_WORK(&local->rx_beacon_work, mac802154_rx_beacon_worker); INIT_DELAYED_WORK(&local->beacon_work, mac802154_beacon_worker); + INIT_WORK(&local->rx_mac_cmd_work, mac802154_rx_mac_cmd_worker); /* init supported flags with 802.15.4 default ranges */ phy->supported.max_minbe = 8; diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index da0628ee3c89..e2434b4fe514 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -47,6 +47,62 @@ void mac802154_rx_beacon_worker(struct work_struct *work) kfree(mac_pkt); } +static bool mac802154_should_answer_beacon_req(struct ieee802154_local *local) +{ + struct cfg802154_beacon_request *beacon_req; + unsigned int interval; + + rcu_read_lock(); + beacon_req = rcu_dereference(local->beacon_req); + if (!beacon_req) { + rcu_read_unlock(); + return false; + } + + interval = beacon_req->interval; + rcu_read_unlock(); + + if (!mac802154_is_beaconing(local)) + return false; + + return interval == IEEE802154_ACTIVE_SCAN_DURATION; +} + +void mac802154_rx_mac_cmd_worker(struct work_struct *work) +{ + struct ieee802154_local *local = + container_of(work, struct ieee802154_local, rx_mac_cmd_work); + struct cfg802154_mac_pkt *mac_pkt; + u8 mac_cmd; + int rc; + + mac_pkt = list_first_entry_or_null(&local->rx_mac_cmd_list, + struct cfg802154_mac_pkt, node); + if (!mac_pkt) + return; + + rc = ieee802154_get_mac_cmd(mac_pkt->skb, &mac_cmd); + if (rc) + goto out; + + switch (mac_cmd) { + case IEEE802154_CMD_BEACON_REQ: + dev_dbg(&mac_pkt->sdata->dev->dev, "processing BEACON REQ\n"); + if (!mac802154_should_answer_beacon_req(local)) + break; + + queue_delayed_work(local->mac_wq, &local->beacon_work, 0); + break; + default: + break; + } + +out: + list_del(&mac_pkt->node); + kfree_skb(mac_pkt->skb); + kfree(mac_pkt); +} + static int ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata, struct sk_buff *skb, const struct ieee802154_hdr *hdr) @@ -140,8 +196,20 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata, list_add_tail(&mac_pkt->node, &sdata->local->rx_beacon_list); queue_work(sdata->local->mac_wq, &sdata->local->rx_beacon_work); return NET_RX_SUCCESS; - case IEEE802154_FC_TYPE_ACK: + case IEEE802154_FC_TYPE_MAC_CMD: + dev_dbg(&sdata->dev->dev, "MAC COMMAND received\n"); + mac_pkt = kzalloc(sizeof(*mac_pkt), GFP_ATOMIC); + if (!mac_pkt) + goto fail; + + mac_pkt->skb = skb_get(skb); + mac_pkt->sdata = sdata; + list_add_tail(&mac_pkt->node, &sdata->local->rx_mac_cmd_list); + queue_work(sdata->local->mac_wq, &sdata->local->rx_mac_cmd_work); + return NET_RX_SUCCESS; + + case IEEE802154_FC_TYPE_ACK: goto fail; case IEEE802154_FC_TYPE_DATA: diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c index 201bfc567a43..618553a2e026 100644 --- a/net/mac802154/scan.c +++ b/net/mac802154/scan.c @@ -403,6 +403,7 @@ void mac802154_beacon_worker(struct work_struct *work) struct cfg802154_beacon_request *beacon_req; struct ieee802154_sub_if_data *sdata; struct wpan_dev *wpan_dev; + u8 interval; int ret; rcu_read_lock(); @@ -423,6 +424,7 @@ void mac802154_beacon_worker(struct work_struct *work) } wpan_dev = beacon_req->wpan_dev; + interval = beacon_req->interval; rcu_read_unlock(); @@ -432,8 +434,9 @@ void mac802154_beacon_worker(struct work_struct *work) dev_err(&sdata->dev->dev, "Beacon could not be transmitted (%d)\n", ret); - queue_delayed_work(local->mac_wq, &local->beacon_work, - local->beacon_interval); + if (interval < IEEE802154_ACTIVE_SCAN_DURATION) + queue_delayed_work(local->mac_wq, &local->beacon_work, + local->beacon_interval); } int mac802154_stop_beacons_locked(struct ieee802154_local *local, @@ -488,13 +491,17 @@ int mac802154_send_beacons_locked(struct ieee802154_sub_if_data *sdata, local->beacon.mhr.source.pan_id = request->wpan_dev->pan_id; local->beacon.mhr.source.extended_addr = request->wpan_dev->extended_addr; local->beacon.mac_pl.beacon_order = request->interval; - local->beacon.mac_pl.superframe_order = request->interval; + if (request->interval <= IEEE802154_MAX_SCAN_DURATION) + local->beacon.mac_pl.superframe_order = request->interval; local->beacon.mac_pl.final_cap_slot = 0xf; local->beacon.mac_pl.battery_life_ext = 0; - /* TODO: Fill this field depending on the coordinator capacity */ + /* TODO: Fill this field with the coordinator situation in the network */ local->beacon.mac_pl.pan_coordinator = 1; local->beacon.mac_pl.assoc_permit = 1; + if (request->interval == IEEE802154_ACTIVE_SCAN_DURATION) + return 0; + /* Start the beacon work */ local->beacon_interval = mac802154_scan_get_channel_time(request->interval, -- cgit v1.2.3 From 822452fb6c696bb2331649ce6fbb49e49261cc71 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 24 Mar 2023 12:05:57 +0100 Subject: net: ieee802154: Handle limited devices with only datagram support Some devices, like HardMAC ones can be a bit limited in the way they handle mac commands. In particular, they might just not support it at all and instead only be able to transmit and receive regular data packets. In this case, they cannot be used for any of the internal management commands that we have introduced so far and must be flagged accordingly. Signed-off-by: Miquel Raynal Acked-by: Alexander Aring Link: https://lore.kernel.org/r/20230324110558.90707-2-miquel.raynal@bootlin.com Signed-off-by: Stefan Schmidt --- include/net/cfg802154.h | 3 +++ net/ieee802154/nl802154.c | 10 ++++++++++ 2 files changed, 13 insertions(+) (limited to 'include') diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 0c2778a836db..e00057984489 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -178,12 +178,15 @@ wpan_phy_cca_cmp(const struct wpan_phy_cca *a, const struct wpan_phy_cca *b) * setting. * @WPAN_PHY_FLAG_STATE_QUEUE_STOPPED: Indicates that the transmit queue was * temporarily stopped. + * @WPAN_PHY_FLAG_DATAGRAMS_ONLY: Indicates that transceiver is only able to + * send/receive datagrams. */ enum wpan_phy_flags { WPAN_PHY_FLAG_TXPOWER = BIT(1), WPAN_PHY_FLAG_CCA_ED_LEVEL = BIT(2), WPAN_PHY_FLAG_CCA_MODE = BIT(3), WPAN_PHY_FLAG_STATE_QUEUE_STOPPED = BIT(4), + WPAN_PHY_FLAG_DATAGRAMS_ONLY = BIT(5), }; struct wpan_phy { diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index a20ac4bb48a4..cd688b51d977 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -1417,6 +1417,11 @@ static int nl802154_trigger_scan(struct sk_buff *skb, struct genl_info *info) return -EINVAL; } + if (wpan_phy->flags & WPAN_PHY_FLAG_DATAGRAMS_ONLY) { + NL_SET_ERR_MSG(info->extack, "PHY only supports datagrams"); + return -EOPNOTSUPP; + } + request = kzalloc(sizeof(*request), GFP_KERNEL); if (!request) return -ENOMEM; @@ -1584,6 +1589,11 @@ nl802154_send_beacons(struct sk_buff *skb, struct genl_info *info) return -EPERM; } + if (wpan_phy->flags & WPAN_PHY_FLAG_DATAGRAMS_ONLY) { + NL_SET_ERR_MSG(info->extack, "PHY only supports datagrams"); + return -EOPNOTSUPP; + } + request = kzalloc(sizeof(*request), GFP_KERNEL); if (!request) return -ENOMEM; -- cgit v1.2.3 From 62aeaeaa1b267c5149abee6b45967a5df3feed58 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 6 Apr 2023 15:21:03 +0200 Subject: drm/aperture: Remove primary argument Only really pci devices have a business setting this - it's for figuring out whether the legacy vga stuff should be nuked too. And with the preceding two patches those are all using the pci version of this. Which means for all other callers primary == false and we can remove it now. v2: - Reorder to avoid compile fail (Thomas) - Include gma500, which retained it's called to the non-pci version. v4: - fix Daniel's S-o-b address v5: - add back an S-o-b tag with Daniel's Intel address Signed-off-by: Daniel Vetter Signed-off-by: Daniel Vetter Signed-off-by: Thomas Zimmermann Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Deepak Rawat Cc: Neil Armstrong Cc: Kevin Hilman Cc: Jerome Brunet Cc: Martin Blumenstingl Cc: Thierry Reding Cc: Jonathan Hunter Cc: Emma Anholt Cc: Helge Deller Cc: David Airlie Cc: Daniel Vetter Cc: linux-hyperv@vger.kernel.org Cc: linux-amlogic@lists.infradead.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-tegra@vger.kernel.org Cc: linux-fbdev@vger.kernel.org Acked-by: Martin Blumenstingl Acked-by: Thierry Reding Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230406132109.32050-4-tzimmermann@suse.de --- drivers/gpu/drm/arm/hdlcd_drv.c | 2 +- drivers/gpu/drm/armada/armada_drv.c | 2 +- drivers/gpu/drm/drm_aperture.c | 11 +++-------- drivers/gpu/drm/gma500/psb_drv.c | 2 +- drivers/gpu/drm/hyperv/hyperv_drm_drv.c | 1 - drivers/gpu/drm/meson/meson_drv.c | 2 +- drivers/gpu/drm/msm/msm_fbdev.c | 2 +- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 2 +- drivers/gpu/drm/stm/drv.c | 2 +- drivers/gpu/drm/sun4i/sun4i_drv.c | 2 +- drivers/gpu/drm/tegra/drm.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.c | 2 +- include/drm/drm_aperture.h | 7 +++---- 13 files changed, 16 insertions(+), 23 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index 9020bf820bc8..12f5a2c7f03d 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -285,7 +285,7 @@ static int hdlcd_drm_bind(struct device *dev) */ if (hdlcd_read(hdlcd, HDLCD_REG_COMMAND)) { hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); - drm_aperture_remove_framebuffers(false, &hdlcd_driver); + drm_aperture_remove_framebuffers(&hdlcd_driver); } drm_mode_config_reset(drm); diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index 0643887800b4..c99ec7078301 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c @@ -95,7 +95,7 @@ static int armada_drm_bind(struct device *dev) } /* Remove early framebuffers */ - ret = drm_aperture_remove_framebuffers(false, &armada_drm_driver); + ret = drm_aperture_remove_framebuffers(&armada_drm_driver); if (ret) { dev_err(dev, "[" DRM_NAME ":%s] can't kick out simple-fb: %d\n", __func__, ret); diff --git a/drivers/gpu/drm/drm_aperture.c b/drivers/gpu/drm/drm_aperture.c index 3b8fdeeafd53..697cffbfd603 100644 --- a/drivers/gpu/drm/drm_aperture.c +++ b/drivers/gpu/drm/drm_aperture.c @@ -32,17 +32,13 @@ * * static int remove_conflicting_framebuffers(struct pci_dev *pdev) * { - * bool primary = false; * resource_size_t base, size; * int ret; * * base = pci_resource_start(pdev, 0); * size = pci_resource_len(pdev, 0); - * #ifdef CONFIG_X86 - * primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; - * #endif * - * return drm_aperture_remove_conflicting_framebuffers(base, size, primary, + * return drm_aperture_remove_conflicting_framebuffers(base, size, * &example_driver); * } * @@ -161,7 +157,6 @@ EXPORT_SYMBOL(devm_aperture_acquire_from_firmware); * drm_aperture_remove_conflicting_framebuffers - remove existing framebuffers in the given range * @base: the aperture's base address in physical memory * @size: aperture size in bytes - * @primary: also kick vga16fb if present * @req_driver: requesting DRM driver * * This function removes graphics device drivers which use the memory range described by @@ -171,9 +166,9 @@ EXPORT_SYMBOL(devm_aperture_acquire_from_firmware); * 0 on success, or a negative errno code otherwise */ int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size, - bool primary, const struct drm_driver *req_driver) + const struct drm_driver *req_driver) { - return aperture_remove_conflicting_devices(base, size, primary, req_driver->name); + return aperture_remove_conflicting_devices(base, size, false, req_driver->name); } EXPORT_SYMBOL(drm_aperture_remove_conflicting_framebuffers); diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index f1e0eed8fea4..4bb06a89e48d 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -428,7 +428,7 @@ static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * TODO: Refactor psb_driver_load() to map vdc_reg earlier. Then we * might be able to read the framebuffer range from the device. */ - ret = drm_aperture_remove_framebuffers(false, &driver); + ret = drm_aperture_remove_framebuffers(&driver); if (ret) return ret; diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c index f830d62a5ce6..a7d2c92d6c6a 100644 --- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c +++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c @@ -74,7 +74,6 @@ static int hyperv_setup_vram(struct hyperv_drm_device *hv, drm_aperture_remove_conflicting_framebuffers(screen_info.lfb_base, screen_info.lfb_size, - false, &hyperv_driver); hv->fb_size = (unsigned long)hv->mmio_megabytes * 1024 * 1024; diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index bb72fda9106d..ca6d1e59e5d9 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -285,7 +285,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) * Remove early framebuffers (ie. simplefb). The framebuffer can be * located anywhere in RAM */ - ret = drm_aperture_remove_framebuffers(false, &meson_driver); + ret = drm_aperture_remove_framebuffers(&meson_driver); if (ret) goto free_drm; diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index d26aa52217ce..16652a5a7018 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -155,7 +155,7 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev) } /* the fw fb could be anywhere in memory */ - ret = drm_aperture_remove_framebuffers(false, dev->driver); + ret = drm_aperture_remove_framebuffers(dev->driver); if (ret) goto fini; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 6e0788d14c10..d97f2edc646b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -140,7 +140,7 @@ static int rockchip_drm_bind(struct device *dev) int ret; /* Remove existing drivers that may own the framebuffer memory. */ - ret = drm_aperture_remove_framebuffers(false, &rockchip_drm_driver); + ret = drm_aperture_remove_framebuffers(&rockchip_drm_driver); if (ret) { DRM_DEV_ERROR(dev, "Failed to remove existing framebuffers - %d.\n", diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c index 422220df7d8c..cb4404b3ce62 100644 --- a/drivers/gpu/drm/stm/drv.c +++ b/drivers/gpu/drm/stm/drv.c @@ -185,7 +185,7 @@ static int stm_drm_platform_probe(struct platform_device *pdev) DRM_DEBUG("%s\n", __func__); - ret = drm_aperture_remove_framebuffers(false, &drv_driver); + ret = drm_aperture_remove_framebuffers(&drv_driver); if (ret) return ret; diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index e49f78a6a8cf..daa7faf72a4b 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c @@ -98,7 +98,7 @@ static int sun4i_drv_bind(struct device *dev) goto unbind_all; /* Remove early framebuffers (ie. simplefb) */ - ret = drm_aperture_remove_framebuffers(false, &sun4i_drv_driver); + ret = drm_aperture_remove_framebuffers(&sun4i_drv_driver); if (ret) goto unbind_all; diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 6ca9f396e55b..d11d259f9399 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -1252,7 +1252,7 @@ static int host1x_drm_probe(struct host1x_device *dev) drm_mode_config_reset(drm); - err = drm_aperture_remove_framebuffers(false, &tegra_drm_driver); + err = drm_aperture_remove_framebuffers(&tegra_drm_driver); if (err < 0) goto hub; diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index c8bf954042e0..823395c23cc3 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -350,7 +350,7 @@ static int vc4_drm_bind(struct device *dev) return -EPROBE_DEFER; } - ret = drm_aperture_remove_framebuffers(false, driver); + ret = drm_aperture_remove_framebuffers(driver); if (ret) return ret; diff --git a/include/drm/drm_aperture.h b/include/drm/drm_aperture.h index 7096703c3949..cbe33b49fd5d 100644 --- a/include/drm/drm_aperture.h +++ b/include/drm/drm_aperture.h @@ -13,14 +13,13 @@ int devm_aperture_acquire_from_firmware(struct drm_device *dev, resource_size_t resource_size_t size); int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size, - bool primary, const struct drm_driver *req_driver); + const struct drm_driver *req_driver); int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev, const struct drm_driver *req_driver); /** * drm_aperture_remove_framebuffers - remove all existing framebuffers - * @primary: also kick vga16fb if present * @req_driver: requesting DRM driver * * This function removes all graphics device drivers. Use this function on systems @@ -30,9 +29,9 @@ int drm_aperture_remove_conflicting_pci_framebuffers(struct pci_dev *pdev, * 0 on success, or a negative errno code otherwise */ static inline int -drm_aperture_remove_framebuffers(bool primary, const struct drm_driver *req_driver) +drm_aperture_remove_framebuffers(const struct drm_driver *req_driver) { - return drm_aperture_remove_conflicting_framebuffers(0, (resource_size_t)-1, primary, + return drm_aperture_remove_conflicting_framebuffers(0, (resource_size_t)-1, req_driver); } -- cgit v1.2.3 From 5fbcc6708fe32ef80122cd2a59ddca9d18b24d6e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 6 Apr 2023 15:21:06 +0200 Subject: video/aperture: Drop primary argument With the preceding patches it's become defunct. Also I'm about to add a different boolean argument, so it's better to keep the confusion down to the absolute minimum. v2: Since the hypervfb patch got droppped (it's only a pci device for gen1 vm, not for gen2) there is one leftover user in an actual driver left to touch. v4: - fixes to commit message - fix Daniel's S-o-b address v5: - add back an S-o-b tag with Daniel's Intel address Signed-off-by: Daniel Vetter Signed-off-by: Daniel Vetter Signed-off-by: Thomas Zimmermann Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: Helge Deller Cc: linux-fbdev@vger.kernel.org Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: "K. Y. Srinivasan" Cc: Haiyang Zhang Cc: Wei Liu Cc: Dexuan Cui Cc: linux-hyperv@vger.kernel.org Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230406132109.32050-7-tzimmermann@suse.de --- drivers/gpu/drm/drm_aperture.c | 2 +- drivers/video/aperture.c | 7 +++---- drivers/video/fbdev/hyperv_fb.c | 2 +- include/linux/aperture.h | 9 ++++----- 4 files changed, 9 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_aperture.c b/drivers/gpu/drm/drm_aperture.c index 697cffbfd603..5729f3bb4398 100644 --- a/drivers/gpu/drm/drm_aperture.c +++ b/drivers/gpu/drm/drm_aperture.c @@ -168,7 +168,7 @@ EXPORT_SYMBOL(devm_aperture_acquire_from_firmware); int drm_aperture_remove_conflicting_framebuffers(resource_size_t base, resource_size_t size, const struct drm_driver *req_driver) { - return aperture_remove_conflicting_devices(base, size, false, req_driver->name); + return aperture_remove_conflicting_devices(base, size, req_driver->name); } EXPORT_SYMBOL(drm_aperture_remove_conflicting_framebuffers); diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c index b378cd1d44d0..a0945027e0df 100644 --- a/drivers/video/aperture.c +++ b/drivers/video/aperture.c @@ -43,7 +43,7 @@ * base = mem->start; * size = resource_size(mem); * - * ret = aperture_remove_conflicting_devices(base, size, false, "example"); + * ret = aperture_remove_conflicting_devices(base, size, "example"); * if (ret) * return ret; * @@ -274,7 +274,6 @@ static void aperture_detach_devices(resource_size_t base, resource_size_t size) * aperture_remove_conflicting_devices - remove devices in the given range * @base: the aperture's base address in physical memory * @size: aperture size in bytes - * @primary: also kick vga16fb if present; only relevant for VGA devices * @name: a descriptive name of the requesting driver * * This function removes devices that own apertures within @base and @size. @@ -283,7 +282,7 @@ static void aperture_detach_devices(resource_size_t base, resource_size_t size) * 0 on success, or a negative errno code otherwise */ int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size, - bool primary, const char *name) + const char *name) { /* * If a driver asked to unregister a platform device registered by @@ -329,7 +328,7 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na base = pci_resource_start(pdev, bar); size = pci_resource_len(pdev, bar); - ret = aperture_remove_conflicting_devices(base, size, primary, name); + ret = aperture_remove_conflicting_devices(base, size, name); if (ret) return ret; } diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c index ec3f6cf05f8c..54f433e09ab8 100644 --- a/drivers/video/fbdev/hyperv_fb.c +++ b/drivers/video/fbdev/hyperv_fb.c @@ -1073,7 +1073,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) info->screen_size = dio_fb_size; getmem_done: - aperture_remove_conflicting_devices(base, size, false, KBUILD_MODNAME); + aperture_remove_conflicting_devices(base, size, KBUILD_MODNAME); if (gen2vm) { /* framebuffer is reallocated, clear screen_info to avoid misuse from kexec */ diff --git a/include/linux/aperture.h b/include/linux/aperture.h index 442f15a57cad..7248727753be 100644 --- a/include/linux/aperture.h +++ b/include/linux/aperture.h @@ -14,7 +14,7 @@ int devm_aperture_acquire_for_platform_device(struct platform_device *pdev, resource_size_t size); int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size, - bool primary, const char *name); + const char *name); int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *name); #else @@ -26,7 +26,7 @@ static inline int devm_aperture_acquire_for_platform_device(struct platform_devi } static inline int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size, - bool primary, const char *name) + const char *name) { return 0; } @@ -39,7 +39,6 @@ static inline int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, /** * aperture_remove_all_conflicting_devices - remove all existing framebuffers - * @primary: also kick vga16fb if present; only relevant for VGA devices * @name: a descriptive name of the requesting driver * * This function removes all graphics device drivers. Use this function on systems @@ -48,9 +47,9 @@ static inline int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, * Returns: * 0 on success, or a negative errno code otherwise */ -static inline int aperture_remove_all_conflicting_devices(bool primary, const char *name) +static inline int aperture_remove_all_conflicting_devices(const char *name) { - return aperture_remove_conflicting_devices(0, (resource_size_t)-1, primary, name); + return aperture_remove_conflicting_devices(0, (resource_size_t)-1, name); } #endif -- cgit v1.2.3 From 116b1c5a364bcbdc40be64d4f3ec9dbc32e264dd Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 6 Apr 2023 15:21:09 +0200 Subject: video/aperture: Provide a VGA helper for gma500 and internal use The hardware for gma500 is different from the rest, as it uses stolen framebuffer memory that is not available via PCI BAR. The regular PCI removal helper cannot detect the framebuffer, while the non-PCI helper misses possible conflicting VGA devices (i.e., a framebuffer or text console). Gma500 therefore calls both helpers to catch all cases. It's confusing as it implies that there's something about the PCI device that requires ownership management. The relationship between the PCI device and the VGA devices is non-obvious. At worst, readers might assume that calling two functions for clearing aperture ownership is a bug in the driver. Hence, move the PCI removal helper's code for VGA functionality into a separate function and call this function from gma500. Documents the purpose of each call to aperture helpers. The change contains comments and example code form the discussion at [1]. v5: * fix grammar in gma500 comment (Javier) Signed-off-by: Thomas Zimmermann Link: https://patchwork.kernel.org/project/dri-devel/patch/20230404201842.567344-1-daniel.vetter@ffwll.ch/ # 1 Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230406132109.32050-10-tzimmermann@suse.de --- drivers/gpu/drm/gma500/psb_drv.c | 48 +++++++++++++++++++++++---------- drivers/video/aperture.c | 58 +++++++++++++++++++++++++++------------- include/linux/aperture.h | 7 +++++ 3 files changed, 81 insertions(+), 32 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index 4bb06a89e48d..8b64f61ffaf9 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -7,6 +7,7 @@ * **************************************************************************/ +#include #include #include #include @@ -19,7 +20,6 @@ #include #include -#include #include #include #include @@ -414,25 +414,45 @@ out_err: return ret; } -static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +/* + * Hardware for gma500 is a hybrid device, which both acts as a PCI + * device (for legacy vga functionality) but also more like an + * integrated display on a SoC where the framebuffer simply + * resides in main memory and not in a special PCI bar (that + * internally redirects to a stolen range of main memory) like all + * other integrated PCI display devices implement it. + * + * To catch all cases we need to remove conflicting firmware devices + * for the stolen system memory and for the VGA functionality. As we + * currently cannot easily find the framebuffer's location in stolen + * memory, we remove all framebuffers here. + * + * TODO: Refactor psb_driver_load() to map vdc_reg earlier. Then + * we might be able to read the framebuffer range from the + * device. + */ +static int gma_remove_conflicting_framebuffers(struct pci_dev *pdev, + const struct drm_driver *req_driver) { - struct drm_psb_private *dev_priv; - struct drm_device *dev; + resource_size_t base = 0; + resource_size_t size = U32_MAX; /* 4 GiB HW limit */ + const char *name = req_driver->name; int ret; - /* - * We cannot yet easily find the framebuffer's location in memory. So - * remove all framebuffers here. Note that we still want the pci special - * handling to kick out vgacon. - * - * TODO: Refactor psb_driver_load() to map vdc_reg earlier. Then we - * might be able to read the framebuffer range from the device. - */ - ret = drm_aperture_remove_framebuffers(&driver); + ret = aperture_remove_conflicting_devices(base, size, name); if (ret) return ret; - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver); + return __aperture_remove_legacy_vga_devices(pdev); +} + +static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + struct drm_psb_private *dev_priv; + struct drm_device *dev; + int ret; + + ret = gma_remove_conflicting_framebuffers(pdev, &driver); if (ret) return ret; diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c index fa71f8257eed..561be8feca96 100644 --- a/drivers/video/aperture.c +++ b/drivers/video/aperture.c @@ -301,6 +301,37 @@ int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t si } EXPORT_SYMBOL(aperture_remove_conflicting_devices); +/** + * __aperture_remove_legacy_vga_devices - remove legacy VGA devices of a PCI devices + * @pdev: PCI device + * + * This function removes VGA devices provided by @pdev, such as a VGA + * framebuffer or a console. This is useful if you have a VGA-compatible + * PCI graphics device with framebuffers in non-BAR locations. Drivers + * should acquire ownership of those memory areas and afterwards call + * this helper to release remaining VGA devices. + * + * If your hardware has its framebuffers accessible via PCI BARS, use + * aperture_remove_conflicting_pci_devices() instead. The function will + * release any VGA devices automatically. + * + * WARNING: Apparently we must remove graphics drivers before calling + * this helper. Otherwise the vga fbdev driver falls over if + * we have vgacon configured. + * + * Returns: + * 0 on success, or a negative errno code otherwise + */ +int __aperture_remove_legacy_vga_devices(struct pci_dev *pdev) +{ + /* VGA framebuffer */ + aperture_detach_devices(VGA_FB_PHYS_BASE, VGA_FB_PHYS_SIZE); + + /* VGA textmode console */ + return vga_remove_vgacon(pdev); +} +EXPORT_SYMBOL(__aperture_remove_legacy_vga_devices); + /** * aperture_remove_conflicting_pci_devices - remove existing framebuffers for PCI devices * @pdev: PCI device @@ -317,7 +348,7 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na { bool primary = false; resource_size_t base, size; - int bar, ret; + int bar, ret = 0; if (pdev == vga_default_device()) primary = true; @@ -334,24 +365,15 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na aperture_detach_devices(base, size); } - if (primary) { - /* - * If this is the primary adapter, there could be a VGA device - * that consumes the VGA framebuffer I/O range. Remove this - * device as well. - */ - aperture_detach_devices(VGA_FB_PHYS_BASE, VGA_FB_PHYS_SIZE); - - /* - * WARNING: Apparently we must kick fbdev drivers before vgacon, - * otherwise the vga fbdev driver falls over. - */ - ret = vga_remove_vgacon(pdev); - if (ret) - return ret; - } + /* + * If this is the primary adapter, there could be a VGA device + * that consumes the VGA framebuffer I/O range. Remove this + * device as well. + */ + if (primary) + ret = __aperture_remove_legacy_vga_devices(pdev); - return 0; + return ret; } EXPORT_SYMBOL(aperture_remove_conflicting_pci_devices); diff --git a/include/linux/aperture.h b/include/linux/aperture.h index 7248727753be..1a9a88b11584 100644 --- a/include/linux/aperture.h +++ b/include/linux/aperture.h @@ -16,6 +16,8 @@ int devm_aperture_acquire_for_platform_device(struct platform_device *pdev, int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size, const char *name); +int __aperture_remove_legacy_vga_devices(struct pci_dev *pdev); + int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *name); #else static inline int devm_aperture_acquire_for_platform_device(struct platform_device *pdev, @@ -31,6 +33,11 @@ static inline int aperture_remove_conflicting_devices(resource_size_t base, reso return 0; } +static inline int __aperture_remove_legacy_vga_devices(struct pci_dev *pdev) +{ + return 0; +} + static inline int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *name) { return 0; -- cgit v1.2.3 From 4d5f872dbc755114628c236e17421629ec522203 Mon Sep 17 00:00:00 2001 From: Iswara Nagulendran Date: Thu, 16 Mar 2023 16:29:06 -0400 Subject: drm/amd/display: Adding support for VESA SCR [HOW&WHY] Write DPCD 721 bit 7 to high, and the appropriate luminance level to DPCD 734-736 if bit 4 from DPCD register 734 is high, indicating that the panel luminance control is enabled from the panel side. Reviewed-by: Anthony Koo Acked-by: Qingqing Zhuo Signed-off-by: Iswara Nagulendran Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc_dp_types.h | 7 ++++++ .../display/dc/link/protocols/link_dp_capability.c | 9 ++++++- .../dc/link/protocols/link_edp_panel_control.c | 29 +++++++++++++++++++--- include/drm/display/drm_dp.h | 3 +++ 4 files changed, 43 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h index 49aab1924665..4a7f6497dc5a 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h @@ -566,6 +566,12 @@ struct dpcd_amd_device_id { uint8_t dal_version_byte2; }; +struct target_luminance_value { + uint8_t byte0; + uint8_t byte1; + uint8_t byte2; +}; + struct dpcd_source_backlight_set { struct { uint8_t byte0; @@ -1225,6 +1231,7 @@ struct dpcd_caps { union dp_main_line_channel_coding_cap channel_coding_cap; union dp_sink_video_fallback_formats fallback_formats; union dp_fec_capability1 fec_cap1; + bool panel_luminance_control; union dp_cable_id cable_id; uint8_t edp_rev; union edp_alpm_caps alpm_caps; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index 5ff5d4e64902..84265dc66bba 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -1450,7 +1450,8 @@ bool read_is_mst_supported(struct dc_link *link) */ static bool dpcd_read_sink_ext_caps(struct dc_link *link) { - uint8_t dpcd_data; + uint8_t dpcd_data = 0; + uint8_t edp_general_cap2 = 0; if (!link) return false; @@ -1459,6 +1460,12 @@ static bool dpcd_read_sink_ext_caps(struct dc_link *link) return false; link->dpcd_sink_ext_caps.raw = dpcd_data; + + if (core_link_read_dpcd(link, DP_EDP_GENERAL_CAP_2, &edp_general_cap2, 1) != DC_OK) + return false; + + link->dpcd_caps.panel_luminance_control = (edp_general_cap2 & DP_EDP_PANEL_LUMINANCE_CONTROL_CAPABLE) != 0; + return true; } diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c index d895046787bc..5ab2de12ccf8 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c @@ -164,14 +164,35 @@ bool edp_set_backlight_level_nits(struct dc_link *link, *(uint16_t *)&dpcd_backlight_set.backlight_transition_time_ms = (uint16_t)transition_time_in_ms; - if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL, + if (!link->dpcd_caps.panel_luminance_control) { + if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL, (uint8_t *)(&dpcd_backlight_set), sizeof(dpcd_backlight_set)) != DC_OK) - return false; + return false; - if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_CONTROL, + if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_CONTROL, &backlight_control, 1) != DC_OK) - return false; + return false; + } else { + const uint8_t backlight_enable = DP_EDP_PANEL_LUMINANCE_CONTROL_ENABLE; + struct target_luminance_value *target_luminance = NULL; + + //if target luminance value is greater than 24 bits, clip the value to 24 bits + if (backlight_millinits > 0xFFFFFF) + backlight_millinits = 0xFFFFFF; + + target_luminance = (struct target_luminance_value *)&backlight_millinits; + + if (core_link_write_dpcd(link, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, + &backlight_enable, + sizeof(backlight_enable)) != DC_OK) + return false; + + if (core_link_write_dpcd(link, DP_EDP_PANEL_TARGET_LUMINANCE_VALUE, + (uint8_t *)(target_luminance), + sizeof(struct target_luminance_value)) != DC_OK) + return false; + } return true; } diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h index 358db4a9f167..d735073fdd81 100644 --- a/include/drm/display/drm_dp.h +++ b/include/drm/display/drm_dp.h @@ -983,6 +983,7 @@ #define DP_EDP_GENERAL_CAP_2 0x703 # define DP_EDP_OVERDRIVE_ENGINE_ENABLED (1 << 0) +# define DP_EDP_PANEL_LUMINANCE_CONTROL_CAPABLE (1 << 4) #define DP_EDP_GENERAL_CAP_3 0x704 /* eDP 1.4 */ # define DP_EDP_X_REGION_CAP_MASK (0xf << 0) @@ -1008,6 +1009,7 @@ # define DP_EDP_DYNAMIC_BACKLIGHT_ENABLE (1 << 4) # define DP_EDP_REGIONAL_BACKLIGHT_ENABLE (1 << 5) # define DP_EDP_UPDATE_REGION_BRIGHTNESS (1 << 6) /* eDP 1.4 */ +# define DP_EDP_PANEL_LUMINANCE_CONTROL_ENABLE (1 << 7) #define DP_EDP_BACKLIGHT_BRIGHTNESS_MSB 0x722 #define DP_EDP_BACKLIGHT_BRIGHTNESS_LSB 0x723 @@ -1032,6 +1034,7 @@ #define DP_EDP_DBC_MINIMUM_BRIGHTNESS_SET 0x732 #define DP_EDP_DBC_MAXIMUM_BRIGHTNESS_SET 0x733 +#define DP_EDP_PANEL_TARGET_LUMINANCE_VALUE 0x734 #define DP_EDP_REGIONAL_BACKLIGHT_BASE 0x740 /* eDP 1.4 */ #define DP_EDP_REGIONAL_BACKLIGHT_0 0x741 /* eDP 1.4 */ -- cgit v1.2.3 From 4f18b9a6711adbc7c76993c734a94ee3f5c61791 Mon Sep 17 00:00:00 2001 From: Bas Nieuwenhuizen Date: Thu, 13 Apr 2023 16:22:53 +0200 Subject: drm/amdgpu: Add support for querying the max ibs in a submission. (v3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This info would be used by radv to figure out when we need to split a submission into multiple submissions. radv currently has a limit of 192 which seems to work for most gfx submissions, but is way too high for e.g. compute or sdma. Userspace is available at https://gitlab.freedesktop.org/bnieuwenhuizen/mesa/-/commits/ib-rejection-v3 v3: Completely rewrote based on suggestion of making it a separate query. Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2498 Reviewed-by: Christian König Signed-off-by: Bas Nieuwenhuizen Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 9 +++++++++ include/uapi/drm/amdgpu_drm.h | 2 ++ 2 files changed, 11 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 0efb38539d70..1a2e342af1c0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -1140,6 +1140,15 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) kfree(caps); return r; } + case AMDGPU_INFO_MAX_IBS: { + uint32_t max_ibs[AMDGPU_HW_IP_NUM]; + + for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) + max_ibs[i] = amdgpu_ring_max_ibs(i); + + return copy_to_user(out, max_ibs, + min((size_t)size, sizeof(max_ibs))) ? -EFAULT : 0; + } default: DRM_DEBUG_KMS("Invalid request %d\n", info->query); return -EINVAL; diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index b6eb90df5d05..6981e59a9401 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -876,6 +876,8 @@ struct drm_amdgpu_cs_chunk_data { #define AMDGPU_INFO_VIDEO_CAPS_DECODE 0 /* Subquery id: Encode */ #define AMDGPU_INFO_VIDEO_CAPS_ENCODE 1 +/* Query the max number of IBs per gang per submission */ +#define AMDGPU_INFO_MAX_IBS 0x22 #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0 #define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff -- cgit v1.2.3 From 91254a4d2e01b8a91c6f0929b77e5fff676a0751 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 17 Apr 2023 14:56:33 +0200 Subject: fbdev: Prepare generic architecture helpers Generic implementations of fb_pgprotect() and fb_is_primary_device() have been in the source code for a long time. Prepare the header file to make use of them. Improve the code by using an inline function for fb_pgprotect() and by removing include statements. The default mode set by fb_pgprotect() is now writecombine, which is what most platforms want. Symbols are protected by preprocessor guards. Architectures that provide a symbol need to define a preprocessor token of the same name and value. Otherwise the header file will provide a generic implementation. This pattern has been taken from . v3: * include the correct header files v2: * use writecombine mappings by default (Arnd) Signed-off-by: Thomas Zimmermann Acked-by: Arnd Bergmann Acked-by: Helge Deller Link: https://patchwork.freedesktop.org/patch/msgid/20230417125651.25126-2-tzimmermann@suse.de --- include/asm-generic/fb.h | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-generic/fb.h b/include/asm-generic/fb.h index f9f18101ed36..c8af99f5a535 100644 --- a/include/asm-generic/fb.h +++ b/include/asm-generic/fb.h @@ -1,13 +1,33 @@ /* SPDX-License-Identifier: GPL-2.0 */ + #ifndef __ASM_GENERIC_FB_H_ #define __ASM_GENERIC_FB_H_ -#include -#define fb_pgprotect(...) do {} while (0) +/* + * Only include this header file from your architecture's . + */ + +#include +#include + +struct fb_info; +struct file; + +#ifndef fb_pgprotect +#define fb_pgprotect fb_pgprotect +static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, + unsigned long off) +{ + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); +} +#endif +#ifndef fb_is_primary_device +#define fb_is_primary_device fb_is_primary_device static inline int fb_is_primary_device(struct fb_info *info) { return 0; } +#endif #endif /* __ASM_GENERIC_FB_H_ */ -- cgit v1.2.3 From 7470849745e6cd746ae773a6e59b309867310181 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 17 Apr 2023 14:56:43 +0200 Subject: video: Move HP PARISC STI core code to shared location STI core files have been located in console and fbdev code. Move the source code and header to the directories for video helpers. Also update the config and build rules such that the code depends on the config symbol CONFIG_STI_CORE, which STI console and STI framebuffer select automatically. Cleans up the console makefile and prepares PARISC to implement fb_is_primary_device() within the arch/ directory. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Arnd Bergmann Acked-by: Helge Deller Link: https://patchwork.freedesktop.org/patch/msgid/20230417125651.25126-12-tzimmermann@suse.de --- drivers/video/Kconfig | 7 + drivers/video/Makefile | 1 + drivers/video/console/Kconfig | 1 + drivers/video/console/Makefile | 4 +- drivers/video/console/sticon.c | 2 +- drivers/video/console/sticore.c | 1172 --------------------------------------- drivers/video/fbdev/Kconfig | 3 +- drivers/video/fbdev/sticore.h | 404 -------------- drivers/video/fbdev/stifb.c | 2 +- drivers/video/sticore.c | 1172 +++++++++++++++++++++++++++++++++++++++ include/video/sticore.h | 404 ++++++++++++++ 11 files changed, 1589 insertions(+), 1583 deletions(-) delete mode 100644 drivers/video/console/sticore.c delete mode 100644 drivers/video/fbdev/sticore.h create mode 100644 drivers/video/sticore.c create mode 100644 include/video/sticore.h (limited to 'include') diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index bf05363d8906..8b2b9ac37c3d 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -11,6 +11,13 @@ config APERTURE_HELPERS Support tracking and hand-over of aperture ownership. Required by graphics drivers for firmware-provided framebuffers. +config STI_CORE + bool + depends on PARISC + help + STI refers to the HP "Standard Text Interface" which is a set of + BIOS routines contained in a ROM chip in HP PA-RISC based machines. + config VIDEO_CMDLINE bool diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 831c9fa57a6c..6bbc03950899 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_APERTURE_HELPERS) += aperture.o +obj-$(CONFIG_STI_CORE) += sticore.o obj-$(CONFIG_VGASTATE) += vgastate.o obj-$(CONFIG_VIDEO_CMDLINE) += cmdline.o obj-$(CONFIG_VIDEO_NOMODESET) += nomodeset.o diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 22cea5082ac4..a2a88d42edf0 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -141,6 +141,7 @@ config STI_CONSOLE depends on PARISC && HAS_IOMEM select FONT_SUPPORT select CRC32 + select STI_CORE default y help The STI console is the builtin display/keyboard on HP-PARISC diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile index db07b784bd2c..fd79016a0d95 100644 --- a/drivers/video/console/Makefile +++ b/drivers/video/console/Makefile @@ -5,8 +5,6 @@ obj-$(CONFIG_DUMMY_CONSOLE) += dummycon.o obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o -obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o +obj-$(CONFIG_STI_CONSOLE) += sticon.o obj-$(CONFIG_VGA_CONSOLE) += vgacon.o obj-$(CONFIG_MDA_CONSOLE) += mdacon.o - -obj-$(CONFIG_FB_STI) += sticore.o diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index 89ad7ade6cf9..d11cfd2d68b5 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -50,7 +50,7 @@ #include -#include "../fbdev/sticore.h" +#include